113 lines
2.8 KiB
TypeScript
113 lines
2.8 KiB
TypeScript
import {
|
||
INITIAL_HC,
|
||
INITIAL_KPI,
|
||
} from './constants'
|
||
import type { DifficultyLevel } from './data/mapConfigs'
|
||
|
||
type GameState = 'idle' | 'playing' | 'paused' | 'victory' | 'defeat'
|
||
|
||
/**
|
||
* 游戏状态管理器(单例)
|
||
* 负责管理 HC(人才储备)、KPI、波次状态,并通过回调事件通知 Scene
|
||
*/
|
||
export class GameManager {
|
||
private static instance: GameManager
|
||
|
||
public hc: number = INITIAL_HC
|
||
public kpi: number = INITIAL_KPI
|
||
public currentWave: number = 0
|
||
public gameState: GameState = 'idle'
|
||
|
||
// 难度与地图状态
|
||
public difficulty: DifficultyLevel = 'normal'
|
||
public currentMapIndex: number = 0 // 0=地图1, 1=地图2, 2=地图3
|
||
public totalWaveCleared: number = 0 // 总计已清理波次
|
||
|
||
// 事件回调(Scene 通过这些 hook 更新 HUD)
|
||
public onHCChange: ((hc: number) => void)[] = []
|
||
public onKPIChange: ((kpi: number) => void)[] = []
|
||
public onGameOver: (() => void)[] = []
|
||
public onVictory: (() => void)[] = []
|
||
|
||
private constructor() {}
|
||
|
||
static getInstance(): GameManager {
|
||
if (!GameManager.instance) {
|
||
GameManager.instance = new GameManager()
|
||
}
|
||
return GameManager.instance
|
||
}
|
||
|
||
/** 设置难度 */
|
||
setDifficulty(d: DifficultyLevel): void {
|
||
this.difficulty = d
|
||
}
|
||
|
||
/** 重置游戏状态(保留难度,重置其他字段) */
|
||
reset(): void {
|
||
this.hc = INITIAL_HC
|
||
this.kpi = INITIAL_KPI
|
||
this.currentWave = 0
|
||
this.gameState = 'idle'
|
||
this.currentMapIndex = 0
|
||
this.totalWaveCleared = 0
|
||
this.onHCChange = []
|
||
this.onKPIChange = []
|
||
this.onGameOver = []
|
||
this.onVictory = []
|
||
// difficulty 保留,不重置
|
||
}
|
||
|
||
/** 重置 HC 到初始值(进入下一关时调用,不带入上一关的余量) */
|
||
resetHC(): void {
|
||
this.hc = INITIAL_HC
|
||
this.onHCChange.forEach(cb => cb(this.hc))
|
||
}
|
||
|
||
/**
|
||
* 扣除 HC,余额不足时返回 false
|
||
*/
|
||
spendHC(amount: number): boolean {
|
||
if (this.hc < amount) return false
|
||
this.hc -= amount
|
||
this.onHCChange.forEach(cb => cb(this.hc))
|
||
return true
|
||
}
|
||
|
||
/**
|
||
* 增加 HC
|
||
*/
|
||
addHC(amount: number): void {
|
||
this.hc += amount
|
||
this.onHCChange.forEach(cb => cb(this.hc))
|
||
}
|
||
|
||
/**
|
||
* 减少 KPI,归零时触发 GameOver
|
||
*/
|
||
reduceKPI(amount: number): void {
|
||
this.kpi = Math.max(0, this.kpi - amount)
|
||
this.onKPIChange.forEach(cb => cb(this.kpi))
|
||
if (this.kpi <= 0 && this.gameState === 'playing') {
|
||
this.gameState = 'defeat'
|
||
this.onGameOver.forEach(cb => cb())
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 增加 KPI(不超过 100)
|
||
*/
|
||
addKPI(amount: number): void {
|
||
this.kpi = Math.min(100, this.kpi + amount)
|
||
this.onKPIChange.forEach(cb => cb(this.kpi))
|
||
}
|
||
|
||
/** 触发胜利 */
|
||
triggerVictory(): void {
|
||
if (this.gameState === 'playing') {
|
||
this.gameState = 'victory'
|
||
this.onVictory.forEach(cb => cb())
|
||
}
|
||
}
|
||
}
|