You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

从Phaser转Canvas开发游戏:角色仅朝向方向可移动问题求助

嘿,从Phaser转原生Canvas做游戏确实得自己啃不少细节——看你说角色只能朝一个方向移动,结合你给出的checkDirection代码片段,我帮你梳理下问题点和修正思路:

可能的核心问题

你当前的代码只处理了isUpKey的情况,而且大概率存在两个常见问题:

  1. 没有正确处理所有方向键的状态切换(比如只监听了keydown没处理keyup,导致按键状态一直为true);
  2. 移动逻辑是“互斥”的(比如用了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
  • 渲染角色的时候,要根据moveXmoveY的值切换精灵表的朝向帧(比如moveX < 0就渲染左向的精灵帧)。

内容的提问来源于stack exchange,提问作者Thunderfist987

火山引擎 最新活动