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

@@ -6,8 +6,11 @@
import { NPC_CONFIG } from '@/config/npcs.js'
import { EVENT_CONFIG } from '@/config/events.js'
import { LOCATION_CONFIG } from '@/config/locations.js'
import { SKILL_CONFIG } from '@/config/skills.js'
import { ENEMY_CONFIG } from '@/config/enemies.js'
import { unlockSkill } from './skillSystem.js'
import { addItemToInventory } from './itemSystem.js'
import { initCombat, getEnvironmentType } from './combatSystem.js'
/**
* 检查并触发事件
@@ -401,11 +404,16 @@ export function processDialogueAction(gameStore, playerStore, action, actionData
// 开始战斗
if (actionData.enemyId) {
gameStore.drawerState.event = false
// TODO: 启动战斗
// 战斗已在探索事件中初始化,这里只是关闭事件抽屉
return { success: true, message: '开始战斗', closeEvent: true }
}
return { success: false, message: '敌人参数错误', closeEvent: false }
case 'flee':
// 逃跑
gameStore.drawerState.event = false
return tryFlee(gameStore, playerStore)
case 'close':
// 直接关闭
return { success: true, message: '', closeEvent: true }
@@ -547,3 +555,108 @@ export function checkScheduledEvents(gameStore, playerStore) {
export function clearScheduledEvents(gameStore) {
gameStore.scheduledEvents = []
}
/**
* 触发探索事件
* @param {Object} gameStore - 游戏Store
* @param {Object} playerStore - 玩家Store
* @returns {Object} 探索结果
*/
export function triggerExploreEvent(gameStore, playerStore) {
const location = LOCATION_CONFIG[playerStore.currentLocation]
if (!location) {
return { success: false, message: '当前位置错误' }
}
// 检查当前位置是否有敌人配置
const availableEnemies = location.enemies || []
if (availableEnemies.length === 0) {
return { success: false, message: '这里没什么可探索的' }
}
// 随机决定探索结果
const roll = Math.random()
// 40% 没发现
if (roll < 0.4) {
triggerEvent(gameStore, 'explore_nothing', {})
return { success: true, type: 'nothing' }
}
// 25% 发现草药
if (roll < 0.65) {
const herbCount = Math.floor(Math.random() * 3) + 1
const result = addItemToInventory(playerStore, 'healing_herb', herbCount, 100)
if (result.success) {
triggerEvent(gameStore, 'explore_find_herb', {})
return { success: true, type: 'find', item: 'healing_herb', count: herbCount }
}
}
// 20% 发现铜币 (1-5枚)
if (roll < 0.85) {
const coinAmount = Math.floor(Math.random() * 5) + 1
playerStore.currency.copper += coinAmount
if (gameStore.addLog) {
gameStore.addLog(`探索发现了 ${coinAmount} 铜币`, 'reward')
}
triggerEvent(gameStore, 'explore_find_coin', { amount: coinAmount })
return { success: true, type: 'coin', amount: coinAmount }
}
// 15% 遭遇敌人
const enemyId = availableEnemies[Math.floor(Math.random() * availableEnemies.length)]
const enemyConfig = ENEMY_CONFIG[enemyId]
if (enemyConfig) {
const environment = getEnvironmentType(playerStore.currentLocation)
gameStore.combatState = initCombat(enemyId, enemyConfig, environment)
gameStore.inCombat = true
triggerEvent(gameStore, 'explore_encounter', {
enemyName: enemyConfig.name,
enemyId
})
return { success: true, type: 'combat', enemyId }
}
// 默认:没发现
triggerEvent(gameStore, 'explore_nothing', {})
return { success: true, type: 'nothing' }
}
/**
* 尝试逃跑
* @param {Object} gameStore - 游戏Store
* @param {Object} playerStore - 玩家Store
* @returns {Object} 逃跑结果
*/
export function tryFlee(gameStore, playerStore) {
// 基础逃跑成功率50%
const baseFleeChance = 0.5
// 敏捷影响逃跑率
const agilityBonus = (playerStore.baseStats?.dexterity || 0) * 0.01
// 装备加成
const equipmentBonus = (playerStore.globalBonus?.fleeRate || 0)
const fleeChance = Math.min(0.9, baseFleeChance + agilityBonus + equipmentBonus)
if (Math.random() < fleeChance) {
// 逃跑成功
gameStore.inCombat = false
gameStore.combatState = null
if (gameStore.addLog) {
gameStore.addLog('成功逃跑了!', 'system')
}
return { success: true, message: '逃跑成功' }
} else {
// 逃跑失败,敌人攻击
if (gameStore.addLog) {
gameStore.addLog('逃跑失败!', 'combat')
}
return { success: false, message: '逃跑失败' }
}
}