使用键盘控制在画布游戏中实现流畅的角色移动

16

我正在使用canvas和JavaScript创建一个横向滚动的无尽太空主题游戏。我只使用上下箭头来控制飞船,并希望实现某种移动缓动效果,以便当我放开键时,飞船不会立即停止。我已经搜索了一些内容,但是没有找到任何有用的东西,而我的尝试也没有成功。这是我尝试过的方法。

Jet.prototype.checkDirection = function () {
if (this.isUpKey) {
    this.drawY -= this.speed;
    if (this.speed < 5) {
        this.speed += 0.1;
    }
}
if (this.isDownKey) {
    this.drawY += this.speed;
    if (this.speed < 5) {
        this.speed += 0.1;
    }
}
if (!this.isUpKey) {
    if (!this.isDownKey) {
        if (this.speed >= 0) {
            this.drawY -= this.speed;
            this.speed -= 1;
        }
    }
}
if (!this.isDownKey) {
    if (!this.isUpKey) {
        if (this.speed >= 0) {
            this.drawY += this.speed;
            this.speed -= 1;
        }
    }
}

2
探索基本的物理模拟力、动量和摩擦。使您的键向飞船添加一种力,它具有质量,并施加摩擦力...通过适当选择参数(质量、摩擦、力),您可以创建各种行为。尽管难度较大,但您以后可以使用它:获得一个奖励,使飞船行动更快,或者是一个负面的奖励,使飞船变得沉重。 - ppeterka
2
用JavaScript重建物理定律就行了。O.O - VoidKing
3个回答

29

你只需要加些摩擦力。这很容易,您可以像下面这样做。

this.speed*=0.98;

数值越低(0.8、0.5等),你减速的速度就越快。

我提供了一个演示,你可以在其中移动并逐渐减速。请自由地调整数值并查看它如何影响演示结果。

现场演示

var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d");

canvas.width = canvas.height = 300;

var x = 150,  //initial x
    y = 150,  // initial y
    velY = 0,
    velX = 0,
    speed = 2, // max speed
    friction = 0.98, // friction
    keys = [];

function update() {
    requestAnimationFrame(update);

    // check the keys and do the movement.
    if (keys[38]) {
        if (velY > -speed) {
            velY--;
        }
    }

    if (keys[40]) {
        if (velY < speed) {
            velY++;
        }
    }
    if (keys[39]) {
        if (velX < speed) {
            velX++;
        }
    }
    if (keys[37]) {
        if (velX > -speed) {
            velX--;
        }
    }

    // apply some friction to y velocity.
    velY *= friction;
    y += velY;

    // apply some friction to x velocity.
    velX *= friction;
    x += velX;

    // bounds checking
    if (x >= 295) {
        x = 295;
    } else if (x <= 5) {
        x = 5;
    }

    if (y > 295) {
        y = 295;
    } else if (y <= 5) {
        y = 5;
    }

    // do the drawing
    ctx.clearRect(0, 0, 300, 300);
    ctx.beginPath();
    ctx.arc(x, y, 5, 0, Math.PI * 2);
    ctx.fill();
}

update();

// key events
document.body.addEventListener("keydown", function (e) {
    keys[e.keyCode] = true;
});
document.body.addEventListener("keyup", function (e) {
    keys[e.keyCode] = false;
});

喜欢你的回答。在update函数的末尾放置requestAnimationFrame(update)调用和在顶部放置有什么区别吗? - macalaca
@macalaca no - ggorlen

2

我认为我会这样做:在键盘松开事件(keyup)时,不要停止飞船,而是编写一个减速函数,并在setInterval中调用该函数以获得所需的效果,然后一旦飞船的速度为零,就调用clearInterval函数。

因此,在keyup事件中,您基本上设置了setInterval(slowShip, 500)。


1
你可以尝试在每一帧上持续降低速度。
if(!playerUp && !playerDown && moveSpeed > 0){
    moveSpeed--;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接