# 时间和定时器系统 ECS 框架提供了完整的时间管理和定时器系统,包括时间缩放、帧时间计算和灵活的定时器调度功能。 ## Time 类 Time 类是框架的时间管理核心,提供了游戏时间相关的所有功能。 ### 基本时间属性 ```typescript import { Time } from '@esengine/esengine'; class GameSystem extends EntitySystem { protected process(entities: readonly Entity[]): void { // 获取帧时间(秒) const deltaTime = Time.deltaTime; // 获取未缩放的帧时间 const unscaledDelta = Time.unscaledDeltaTime; // 获取游戏总时间 const totalTime = Time.totalTime; // 获取当前帧数 const frameCount = Time.frameCount; console.log(`第 ${frameCount} 帧,帧时间: ${deltaTime}s,总时间: ${totalTime}s`); } } ``` ### 时间缩放 Time 类支持时间缩放功能,可以实现慢动作、快进等效果: ```typescript class TimeControlSystem extends EntitySystem { public enableSlowMotion(): void { // 设置为慢动作(50%速度) Time.timeScale = 0.5; console.log('慢动作模式启用'); } public enableFastForward(): void { // 设置为快进(200%速度) Time.timeScale = 2.0; console.log('快进模式启用'); } public pauseGame(): void { // 暂停游戏(时间静止) Time.timeScale = 0; console.log('游戏暂停'); } public resumeNormalSpeed(): void { // 恢复正常速度 Time.timeScale = 1.0; console.log('恢复正常速度'); } protected process(entities: readonly Entity[]): void { // deltaTime 会受到 timeScale 影响 const scaledDelta = Time.deltaTime; // 受时间缩放影响 const realDelta = Time.unscaledDeltaTime; // 不受时间缩放影响 for (const entity of entities) { const movement = entity.getComponent(Movement); if (movement) { // 使用缩放时间进行游戏逻辑更新 movement.update(scaledDelta); } const ui = entity.getComponent(UIComponent); if (ui) { // UI 动画使用真实时间,不受游戏时间缩放影响 ui.update(realDelta); } } } } ``` ### 时间检查工具 ```typescript class CooldownSystem extends EntitySystem { private lastAttackTime = 0; private lastSpawnTime = 0; constructor() { super(Matcher.all(Weapon)); } protected process(entities: readonly Entity[]): void { // 检查攻击冷却 if (Time.checkEvery(1.5, this.lastAttackTime)) { this.performAttack(); this.lastAttackTime = Time.totalTime; } // 检查生成间隔 if (Time.checkEvery(3.0, this.lastSpawnTime)) { this.spawnEnemy(); this.lastSpawnTime = Time.totalTime; } } private performAttack(): void { console.log('执行攻击!'); } private spawnEnemy(): void { console.log('生成敌人!'); } } ``` ## Core.schedule 定时器系统 Core 提供了强大的定时器调度功能,可以创建一次性或重复执行的定时器。 ### 基本定时器使用 ```typescript import { Core } from '@esengine/esengine'; class GameScene extends Scene { protected initialize(): void { // 创建一次性定时器 this.createOneTimeTimers(); // 创建重复定时器 this.createRepeatingTimers(); // 创建带上下文的定时器 this.createContextTimers(); } private createOneTimeTimers(): void { // 2秒后执行一次 Core.schedule(2.0, false, null, (timer) => { console.log('2秒延迟执行'); }); // 5秒后显示提示 Core.schedule(5.0, false, this, (timer) => { const scene = timer.getContext(); scene.showTip('游戏提示:5秒已过!'); }); } private createRepeatingTimers(): void { // 每秒重复执行 const heartbeatTimer = Core.schedule(1.0, true, null, (timer) => { console.log(`游戏心跳 - 总时间: ${Time.totalTime.toFixed(1)}s`); }); // 可以保存定时器引用用于后续控制 this.saveTimerReference(heartbeatTimer); } private createContextTimers(): void { const gameData = { score: 0, level: 1 }; // 每2秒增加分数 Core.schedule(2.0, true, gameData, (timer) => { const data = timer.getContext(); data.score += 10; console.log(`分数增加!当前分数: ${data.score}`); }); } private saveTimerReference(timer: any): void { // 可以稍后停止定时器 setTimeout(() => { timer.stop(); console.log('定时器已停止'); }, 10000); // 10秒后停止 } private showTip(message: string): void { console.log('提示:', message); } } ``` ### 定时器控制 ```typescript class TimerControlExample { private attackTimer: any; private spawnerTimer: any; public startCombat(): void { // 启动攻击定时器 this.attackTimer = Core.schedule(0.5, true, this, (timer) => { const self = timer.getContext(); self.performAttack(); }); // 启动敌人生成定时器 this.spawnerTimer = Core.schedule(3.0, true, null, (timer) => { this.spawnEnemy(); }); } public stopCombat(): void { // 停止所有战斗相关定时器 if (this.attackTimer) { this.attackTimer.stop(); console.log('攻击定时器已停止'); } if (this.spawnerTimer) { this.spawnerTimer.stop(); console.log('生成定时器已停止'); } } public resetAttackTimer(): void { // 重置攻击定时器 if (this.attackTimer) { this.attackTimer.reset(); console.log('攻击定时器已重置'); } } private performAttack(): void { console.log('执行攻击'); } private spawnEnemy(): void { console.log('生成敌人'); } } ``` ### 复杂定时器场景 ```typescript class AdvancedTimerUsage { private powerUpDuration = 0; private powerUpActive = false; public activatePowerUp(): void { if (this.powerUpActive) { console.log('能力提升已激活'); return; } this.powerUpActive = true; this.powerUpDuration = 10; // 10秒持续时间 console.log('能力提升激活!'); // 每秒更新剩余时间 const countdownTimer = Core.schedule(1.0, true, this, (timer) => { const self = timer.getContext(); self.powerUpDuration--; console.log(`能力提升剩余时间: ${self.powerUpDuration}秒`); if (self.powerUpDuration <= 0) { self.deactivatePowerUp(); timer.stop(); // 停止倒计时 } }); // 能力提升结束定时器(备用) Core.schedule(10.0, false, this, (timer) => { const self = timer.getContext(); if (self.powerUpActive) { self.deactivatePowerUp(); } }); } private deactivatePowerUp(): void { this.powerUpActive = false; this.powerUpDuration = 0; console.log('能力提升结束'); } // 创建波次攻击定时器 public startWaveAttack(): void { let waveCount = 0; const maxWaves = 5; const waveTimer = Core.schedule(2.0, true, { waveCount, maxWaves }, (timer) => { const context = timer.getContext<{ waveCount: number, maxWaves: number }>(); context.waveCount++; console.log(`第 ${context.waveCount} 波攻击!`); if (context.waveCount >= context.maxWaves) { console.log('所有波次攻击完成'); timer.stop(); } }); } // 创建条件定时器 public startConditionalTimer(): void { Core.schedule(0.1, true, this, (timer) => { const self = timer.getContext(); // 检查某个条件 if (self.shouldStopTimer()) { console.log('条件满足,停止定时器'); timer.stop(); return; } // 继续执行定时器逻辑 self.performTimerAction(); }); } private shouldStopTimer(): boolean { // 检查停止条件 return Time.totalTime > 30; // 30秒后停止 } private performTimerAction(): void { console.log('执行定时器动作'); } } ``` ## 实际应用示例 ### 技能冷却系统 ```typescript class SkillCooldownSystem extends EntitySystem { constructor() { super(Matcher.all(SkillComponent)); } protected process(entities: readonly Entity[]): void { for (const entity of entities) { const skill = entity.getComponent(SkillComponent); // 更新技能冷却 if (skill.isOnCooldown) { skill.cooldownRemaining -= Time.deltaTime; if (skill.cooldownRemaining <= 0) { skill.cooldownRemaining = 0; skill.isOnCooldown = false; console.log(`技能 ${skill.name} 冷却完成`); } } } } public useSkill(entity: Entity, skillName: string): boolean { const skill = entity.getComponent(SkillComponent); if (skill.isOnCooldown) { console.log(`技能 ${skillName} 还在冷却中,剩余 ${skill.cooldownRemaining.toFixed(1)}秒`); return false; } // 执行技能 this.executeSkill(entity, skill); // 开始冷却 skill.isOnCooldown = true; skill.cooldownRemaining = skill.cooldownDuration; return true; } private executeSkill(entity: Entity, skill: SkillComponent): void { console.log(`执行技能: ${skill.name}`); // 技能效果逻辑 } } ``` ### 游戏状态定时器 ```typescript class GameStateManager { private gamePhase = 'preparation'; private phaseTimer: any; public startGame(): void { this.startPreparationPhase(); } private startPreparationPhase(): void { this.gamePhase = 'preparation'; console.log('准备阶段开始 - 10秒准备时间'); this.phaseTimer = Core.schedule(10.0, false, this, (timer) => { const self = timer.getContext(); self.startCombatPhase(); }); } private startCombatPhase(): void { this.gamePhase = 'combat'; console.log('战斗阶段开始 - 60秒战斗时间'); this.phaseTimer = Core.schedule(60.0, false, this, (timer) => { const self = timer.getContext(); self.startResultPhase(); }); // 每10秒刷新一波敌人 Core.schedule(10.0, true, null, (timer) => { if (this.gamePhase === 'combat') { this.spawnEnemyWave(); } else { timer.stop(); // 战斗阶段结束时停止刷新 } }); } private startResultPhase(): void { this.gamePhase = 'result'; console.log('结算阶段开始 - 5秒结算时间'); this.phaseTimer = Core.schedule(5.0, false, this, (timer) => { const self = timer.getContext(); self.endGame(); }); } private endGame(): void { console.log('游戏结束'); this.gamePhase = 'ended'; } private spawnEnemyWave(): void { console.log('刷新敌人波次'); } public getCurrentPhase(): string { return this.gamePhase; } } ``` ## 最佳实践 ### 1. 合理使用时间类型 ```typescript class MovementSystem extends EntitySystem { protected process(entities: readonly Entity[]): void { for (const entity of entities) { const movement = entity.getComponent(Movement); // ✅ 游戏逻辑使用缩放时间 movement.position.x += movement.velocity.x * Time.deltaTime; // ✅ UI动画使用真实时间(不受游戏暂停影响) const ui = entity.getComponent(UIAnimation); if (ui) { ui.update(Time.unscaledDeltaTime); } } } } ``` ### 2. 定时器管理 ```typescript class TimerManager { private timers: any[] = []; public createManagedTimer(duration: number, repeats: boolean, callback: () => void): any { const timer = Core.schedule(duration, repeats, null, callback); this.timers.push(timer); return timer; } public stopAllTimers(): void { for (const timer of this.timers) { timer.stop(); } this.timers = []; } public cleanupCompletedTimers(): void { this.timers = this.timers.filter(timer => !timer.isDone); } } ``` ### 3. 避免过多的定时器 ```typescript // ❌ 避免:为每个实体创建定时器 class BadExample extends EntitySystem { protected onAdded(entity: Entity): void { Core.schedule(1.0, true, entity, (timer) => { // 每个实体一个定时器,性能差 }); } } // ✅ 推荐:在系统中统一管理时间 class GoodExample extends EntitySystem { private lastUpdateTime = 0; protected process(entities: readonly Entity[]): void { // 每秒执行一次逻辑 if (Time.checkEvery(1.0, this.lastUpdateTime)) { this.processAllEntities(entities); this.lastUpdateTime = Time.totalTime; } } private processAllEntities(entities: readonly Entity[]): void { // 批量处理所有实体 } } ``` ### 4. 定时器上下文使用 ```typescript interface TimerContext { entityId: number; duration: number; onComplete: () => void; } class ContextualTimerExample { public createEntityTimer(entityId: number, duration: number, onComplete: () => void): void { const context: TimerContext = { entityId, duration, onComplete }; Core.schedule(duration, false, context, (timer) => { const ctx = timer.getContext(); console.log(`实体 ${ctx.entityId} 的定时器完成`); ctx.onComplete(); }); } } ``` 时间和定时器系统是游戏开发中的重要工具,正确使用这些功能能让你的游戏逻辑更加精确和可控。