Phaser 3中finished变量未按预期递增问题求助
Phaser 3小游戏完成标记失效问题排查与解决方案
问题核心原因
最常见的触发问题的原因是按键事件回调中的this指向错误:用普通函数作为Phaser按键回调时,回调内的this默认指向输入事件管理器,而非当前场景实例,导致你修改的this.finished根本不是场景中定义的变量。其次可能是计数判断逻辑有漏洞,比如计数到8后未及时终止重复触发,或是this.finished初始化位置错误被意外重置。
修复后的完整代码示例
以下是适配你逻辑的可运行代码,重点解决this指向问题,同时完善计数与完成标记逻辑:
export default class MiniGameScene extends Phaser.Scene { constructor() { super('MiniGameScene'); } init() { // 初始化小游戏核心状态 this.mini = true; this.houseRepair = true; this.plumbing = true; this.electricity = true; this.gardening = true; // 计算需要完成的任务总数 this.fixed = 4; if (!this.houseRepair) this.fixed--; if (!this.plumbing) this.fixed--; if (!this.electricity) this.fixed--; if (!this.gardening) this.fixed--; this.finished = 0; // 初始化各任务计数 this.hammerCount = 0; this.wrenchCount = 0; this.screwdriverCount = 0; this.shearsCount = 0; } create() { // 创建任务对应图片(示例) this.hammerSprite = this.add.sprite(100, 200, 'hammer'); this.wrenchSprite = this.add.sprite(300, 200, 'wrench'); this.screwdriverSprite = this.add.sprite(500, 200, 'screwdriver'); this.shearsSprite = this.add.sprite(700, 200, 'shears'); // 绑定按键事件,用箭头函数确保this指向当前场景 this.input.keyboard.on('keydown-A', () => this.handleTask('hammer')); this.input.keyboard.on('keydown-S', () => this.handleTask('wrench')); this.input.keyboard.on('keydown-D', () => this.handleTask('screwdriver')); this.input.keyboard.on('keydown-F', () => this.handleTask('shears')); } handleTask(taskType) { if (!this.mini) return; // 小游戏未启动或已完成,直接终止执行 const countKey = `${taskType}Count`; const spriteKey = `${taskType}Sprite`; // 计数递增 this[countKey]++; // 检查当前任务是否完成 if (this[countKey] === 8) { // 销毁对应图片 this[spriteKey].destroy(); // 完成任务数+1 this.finished++; // 禁用当前任务的按键触发,避免重复计数 this.input.keyboard.off(`keydown-${taskType.charAt(0).toUpperCase()}`); // 检查是否所有任务完成 this.checkCompletion(); } } checkCompletion() { if (this.finished === this.fixed) { this.mini = false; console.log('小游戏已完成'); // 若需通知其他代码,可触发自定义事件 this.events.emit('miniGameDone'); } } }
关键修复点
- 箭头函数绑定回调:保证按键回调内的
this始终指向当前场景实例,正确修改场景的finished变量。 - 任务完成后禁用按键:避免同一任务重复触发计数与完成操作。
- 拆分独立逻辑方法:将按键处理与完成检查分离,代码更清晰,便于调试。
- 自定义事件通知:通过Phaser事件系统
this.events.emit向其他代码传递完成信号,外部可通过this.scene.get('MiniGameScene').on('miniGameDone', () => { ... })监听。
额外排查建议
- 打开浏览器开发者工具Console面板,在
this.finished++行添加console.log(this.finished),确认是否真的未执行。 - 检查
this.finished的初始化位置,确保每次启动小游戏时都重置为0,避免在update方法中被意外覆盖。 - 验证
this.fixed的计算逻辑,确认四个布尔变量的状态与实际需要完成的任务数匹配。
内容的提问来源于stack exchange,提问作者EmptyStone
相关产品推荐
相关产品推荐

