feat: 实现游戏核心系统和UI组件

核心系统:
- combatSystem: 战斗逻辑、伤害计算、战斗状态管理
- skillSystem: 技能系统、技能解锁、经验值、里程碑
- taskSystem: 任务系统、任务类型、任务执行和完成
- eventSystem: 事件系统、随机事件处理
- environmentSystem: 环境系统、时间流逝、区域效果
- levelingSystem: 升级系统、属性成长
- soundSystem: 音效系统

配置文件:
- enemies: 敌人配置、掉落表
- events: 事件配置、事件效果
- items: 物品配置、装备属性
- locations: 地点配置、探索事件
- skills: 技能配置、技能树

UI组件:
- CraftingDrawer: 制造界面
- InventoryDrawer: 背包界面
- 其他UI优化和动画

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Claude
2026-01-23 16:20:10 +08:00
parent 021f6a54f5
commit 16223c89a5
25 changed files with 2731 additions and 318 deletions

View File

@@ -105,9 +105,10 @@ import { useGameStore } from '@/store/game'
import { usePlayerStore } from '@/store/player'
import { LOCATION_CONFIG } from '@/config/locations'
import { NPC_CONFIG } from '@/config/npcs.js'
import { ENEMY_CONFIG } from '@/config/enemies.js'
import { ENEMY_CONFIG, getRandomEnemyForLocation } from '@/config/enemies.js'
import { getShopConfig } from '@/config/shop.js'
import { initCombat, getEnvironmentType } from '@/utils/combatSystem.js'
import { triggerExploreEvent, tryFlee } from '@/utils/eventSystem.js'
import TextButton from '@/components/common/TextButton.vue'
import ProgressBar from '@/components/common/ProgressBar.vue'
import FilterTabs from '@/components/common/FilterTabs.vue'
@@ -151,10 +152,10 @@ const availableLocations = computed(() => {
// 检查解锁条件
if (loc.unlockCondition) {
if (loc.unlockCondition.type === 'kill') {
// 检查击杀条件(需要追踪击杀数
const killCount = player.flags[`kill_${loc.unlockCondition.target}`] || 0
// 检查击杀条件(使用统一的killCount存储
const killCount = (player.killCount && player.killCount[loc.unlockCondition.target]) || 0
locked = killCount < loc.unlockCondition.count
lockReason = `需要击杀${loc.unlockCondition.count}${getEnemyName(loc.unlockCondition.target)}`
lockReason = `需要击杀${loc.unlockCondition.count}${getEnemyName(loc.unlockCondition.target)} (当前: ${killCount})`
} else if (loc.unlockCondition.type === 'item') {
// 检查物品条件
const hasItem = player.inventory.some(i => i.id === loc.unlockCondition.item)
@@ -191,7 +192,8 @@ const currentActions = computed(() => {
trade: { id: 'trade', label: '交易', type: 'default' },
explore: { id: 'explore', label: '探索', type: 'warning' },
combat: { id: 'combat', label: '战斗', type: 'danger' },
read: { id: 'read', label: '阅读', type: 'default' }
read: { id: 'read', label: '阅读', type: 'default' },
crafting: { id: 'crafting', label: '制造', type: 'primary' }
}
// 战斗中只显示战斗相关
@@ -302,33 +304,37 @@ function doAction(actionId) {
break
case 'explore':
game.addLog('开始探索...', 'info')
// 探索逻辑
const exploreResult = triggerExploreEvent(game, player)
if (!exploreResult.success) {
game.addLog(exploreResult.message, 'info')
}
break
case 'combat':
startCombat()
break
case 'flee':
game.addLog('尝试逃跑...', 'combat')
// 逃跑逻辑
const fleeResult = tryFlee(game, player)
if (!fleeResult.success) {
// 逃跑失败,玩家会多受到一次攻击(在战斗循环中处理)
}
break
case 'read':
game.addLog('找个安静的地方阅读...', 'info')
break
case 'crafting':
game.drawerState.crafting = true
game.addLog('打开制造界面...', 'info')
break
}
}
function startCombat() {
const current = LOCATION_CONFIG[player.currentLocation]
if (!current || !current.enemies || current.enemies.length === 0) {
game.addLog('这里没有敌人', 'info')
return
}
const enemyId = current.enemies[0]
const enemyConfig = ENEMY_CONFIG[enemyId]
// 使用新的敌人获取函数
const enemyConfig = getRandomEnemyForLocation(player.currentLocation)
if (!enemyConfig) {
game.addLog('敌人配置错误', 'error')
game.addLog('这里没有敌人', 'info')
return
}
@@ -337,8 +343,8 @@ function startCombat() {
// 获取环境类型
const environment = getEnvironmentType(player.currentLocation)
// 使用 initCombat 初始化战斗(包含 expReward 和 drops
game.combatState = initCombat(enemyId, enemyConfig, environment)
// 使用 initCombat 初始化战斗
game.combatState = initCombat(enemyConfig.id, enemyConfig, environment)
game.inCombat = true
}
@@ -368,8 +374,8 @@ function toggleAutoCombat() {
game.addLog('自动战斗已开启 - 战斗结束后自动寻找新敌人', 'info')
// 如果当前不在战斗中且在危险区域,立即开始战斗
if (!game.inCombat) {
const current = LOCATION_CONFIG[player.currentLocation]
if (current && current.enemies && current.enemies.length > 0) {
const enemyConfig = getRandomEnemyForLocation(player.currentLocation)
if (enemyConfig) {
startCombat()
}
}