Phaser 3中GameState对象部分场景可用、部分失效问题排查
Phaser 3 中键盘回调修改gameState报错的原因与解决方法
核心原因
这是典型的函数上下文this指向混乱问题:
- 你直接在场景方法里访问
this.gameState时,this指向的是Phaser场景实例,也就是定义gameState的上下文,所以能正常访问。 - 但传给
input.keyboard.on的普通function回调,在事件触发时,内部的this会指向键盘输入管理器对象,而非你的场景实例。这时候this.gameState就是undefined,自然会触发“无法设置undefined的属性”的错误。 - 另外两个属性没出问题只是你没在回调里操作它们,本质和
selectedBlock没有区别。
三种可行的解决方法
方法1:使用箭头函数(最推荐)
箭头函数不会创建自己的this,会继承外部作用域的this指向,完美适配这种场景:
this.input.keyboard.on("keydown", (event) => { if (event.keyCode === 49) { this.gameState.selectedBlock = 1; } else if (event.keyCode === 50) { this.gameState.selectedBlock = 2; } else if (event.keyCode === 51) { this.gameState.selectedBlock = 3; } else if (event.keyCode === 52) { this.gameState.selectedBlock = 4; } });
方法2:提前缓存场景实例的this
在回调外部把场景的this存到变量里,回调内用这个变量访问gameState:
const currentScene = this; this.input.keyboard.on("keydown", function (event) { if (event.keyCode === 49) { currentScene.gameState.selectedBlock = 1; } else if (event.keyCode === 50) { currentScene.gameState.selectedBlock = 2; } else if (event.keyCode === 51) { currentScene.gameState.selectedBlock = 3; } else if (event.keyCode === 52) { currentScene.gameState.selectedBlock = 4; } });
方法3:用bind强制绑定this
通过bind方法把回调函数的this固定为场景实例:
this.input.keyboard.on("keydown", function (event) { if (event.keyCode === 49) { this.gameState.selectedBlock = 1; } else if (event.keyCode === 50) { this.gameState.selectedBlock = 2; } else if (event.keyCode === 51) { this.gameState.selectedBlock = 3; } else if (event.keyCode === 52) { this.gameState.selectedBlock = 4; } }.bind(this));
内容的提问来源于stack exchange,提问作者Vatsa Pandey
相关产品推荐
相关产品推荐

