Phaser报错:Cannot read property 'body' of undefined 问题求助
解决Phaser中Update函数调用Player对象报错的问题
看起来你遇到的核心问题是异步初始化导致的player变量未定义,加上一些小的变量未初始化问题,我来一步步帮你修复:
错误根源分析
当游戏启动时,Game.create里调用了Client.askNewPlayer()——这应该是一个向服务器请求创建玩家的异步操作。但Phaser的update函数会在create执行完后立刻进入循环,这时候Game.addNewPlayer还没被服务器触发调用,全局的player变量还是undefined,所以访问player.body.velocity自然会报错。另外你的代码里cursors变量也没初始化,后续也会出问题。
具体修复方案
1. 用玩家ID跟踪本地玩家,抛弃不可靠的全局player
首先,替换原来的全局player变量,新增一个存储本地玩家ID的变量:
// 删掉原来的 var player; var localPlayerId; // 新增:存储当前客户端控制的玩家ID var layer; var map; var blockedLayer;
然后修改Game.addNewPlayer,把新创建的玩家存入playerMap,同时标记本地玩家ID:
Game.addNewPlayer = function(id,x,y){ var newPlayer = game.add.sprite(x,y,'sprite'); game.physics.arcade.enable(newPlayer); newPlayer.body.collideWorldBounds = true; Game.playerMap[id] = newPlayer; // 标记当前客户端控制的玩家(如果这个id就是本地玩家的标识) localPlayerId = id; };
2. 在Update函数里先检查玩家是否存在
修改Game.update,先从playerMap里获取本地玩家,确认存在后再执行逻辑,同时补上缺失的cursors初始化:
Game.update = function(){ // 先获取本地玩家,不存在就直接跳过本次update循环 var player = Game.playerMap[localPlayerId]; if (!player) return; game.physics.arcade.collide(player, blockedLayer); player.body.velocity.y = 0; player.body.velocity.x = 0; // 初始化方向键(只执行一次) if (!this.cursors) { this.cursors = game.input.keyboard.createCursorKeys(); } if(this.cursors.up.isDown) { player.body.velocity.y -= 50; } else if(this.cursors.down.isDown) { player.body.velocity.y += 50; } if(this.cursors.left.isDown) { player.body.velocity.x -= 50; } else if(this.cursors.right.isDown) { player.body.velocity.x += 50; } };
3. 为什么这样有效?
- 我们不再依赖全局的
player变量,而是从playerMap里根据ID获取玩家,这更适合多人游戏的场景,后续添加其他玩家也不会造成变量混乱。 - 在
update开头判断玩家是否存在,避免了异步初始化完成前的报错——只要服务器还没返回玩家数据,update就会跳过逻辑,直到玩家被创建。 - 补上了
cursors的初始化,解决了后续可能出现的方向键无响应问题。
额外小提示
如果你的Client.askNewPlayer有回调可以直接拿到本地玩家ID,最好在回调里设置localPlayerId,而不是在addNewPlayer里直接赋值,避免把其他玩家误判为本地玩家:
Client.askNewPlayer(function(localId) { localPlayerId = localId; });
内容的提问来源于stack exchange,提问作者Ycaroh
相关产品推荐
相关产品推荐

