从Phaser转Canvas开发游戏:角色仅朝向方向可移动问题求助
嘿,从Phaser转原生Canvas做游戏确实得自己啃不少细节——看你说角色只能朝一个方向移动,结合你给出的checkDirection代码片段,我帮你梳理下问题点和修正思路:
可能的核心问题
你当前的代码只处理了isUpKey的情况,而且大概率存在两个常见问题:
- 没有正确处理所有方向键的状态切换(比如只监听了
keydown没处理keyup,导致按键状态一直为true); - 移动逻辑是“互斥”的(比如用了
else if),或者没有同时检测多个方向键的输入。
修正后的代码示例
先补全checkDirection的完整逻辑,同时确保按键状态能正确重置:
1. 完善角色的方向检测与移动逻辑
Player.prototype.checkDirection = function () { let newDrawX = this.drawX; let newDrawY = this.drawY; obstacleCollision = false; // 独立判断每个方向,支持斜向移动(如果不需要斜向,再改成else if) if (this.isUpKey && !obstacleCollision) { newDrawY -= this.speed; this.moveY = -this.speed; // 记录Y方向移动向量(用于精灵朝向) } if (this.isDownKey && !obstacleCollision) { newDrawY += this.speed; this.moveY = this.speed; } if (this.isLeftKey && !obstacleCollision) { newDrawX -= this.speed; this.moveX = -this.speed; // 记录X方向移动向量 } if (this.isRightKey && !obstacleCollision) { newDrawX += this.speed; this.moveX = this.speed; } // 碰撞检测:如果碰到障碍物,回滚坐标 if (obstacleCollision) { newDrawX = this.drawX; newDrawY = this.drawY; } // 没有按键按下时,重置移动向量 if (!this.isUpKey && !this.isDownKey) this.moveY = 0; if (!this.isLeftKey && !this.isRightKey) this.moveX = 0; // 更新角色的实际绘制坐标 this.drawX = newDrawX; this.drawY = newDrawY; };
2. 正确处理键盘事件(关键!)
很多人会忽略keyup事件,导致按键状态一直处于激活状态,角色就会一直朝一个方向跑:
// 先初始化角色的按键状态属性 function Player() { this.isUpKey = false; this.isDownKey = false; this.isLeftKey = false; this.isRightKey = false; // ...其他属性:drawX、drawY、speed等 } // 监听键盘按下 document.addEventListener('keydown', (e) => { switch(e.key) { case 'ArrowUp': player.isUpKey = true; break; case 'ArrowDown': player.isDownKey = true; break; case 'ArrowLeft': player.isLeftKey = true; break; case 'ArrowRight': player.isRightKey = true; break; } }); // 监听键盘松开,必须重置状态! document.addEventListener('keyup', (e) => { switch(e.key) { case 'ArrowUp': player.isUpKey = false; break; case 'ArrowDown': player.isDownKey = false; break; case 'ArrowLeft': player.isLeftKey = false; break; case 'ArrowRight': player.isRightKey = false; break; } });
额外注意点
- 如果不需要斜向移动,把方向判断改成
else if即可,这样同一时间只会处理一个方向; - 碰撞检测的逻辑要放在坐标更新后,检测
newDrawX/newDrawY是否进入障碍物区域,一旦碰撞就把坐标回滚到原来的drawX/drawY; - 渲染角色的时候,要根据
moveX和moveY的值切换精灵表的朝向帧(比如moveX < 0就渲染左向的精灵帧)。
内容的提问来源于stack exchange,提问作者Thunderfist987




