You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 15:35:50