HTML5/Javascript-我的用户触发画布动画起伏

HTML5/Javascript-我的用户触发画布动画起伏,javascript,html5-canvas,Javascript,Html5 Canvas,我有一个简单的概念。当玩家按W、A、S或D时,画布上的图像会相应移动。然而,这会导致非常不稳定的动画,我不知道为什么(尽管我认为这与我的事件侦听器有关)。下面是我的代码 var playerXPos = 10; var playerYPos = 10; var playerImg = new Image(); playerImg.src = "knight.png"; function mainGameLoop(){ window.requestAnimationFrame(mainG

我有一个简单的概念。当玩家按W、A、S或D时,画布上的图像会相应移动。然而,这会导致非常不稳定的动画,我不知道为什么(尽管我认为这与我的事件侦听器有关)。下面是我的代码

var playerXPos = 10;
var playerYPos = 10;
var playerImg = new Image();
playerImg.src = "knight.png";

function mainGameLoop(){
    window.requestAnimationFrame(mainGameLoop);
    c = document.getElementById("gameCanvas").getContext("2d");


    c.clearRect(0,0,1000,500);

    c.drawImage(playerImg,playerXPos,playerYPos);
}
window.requestAnimationFrame(mainGameLoop);


    window.addEventListener("keydown", onKeyDown, false);
    window.addEventListener("keyup", onKeyUp, false);
    window.addEventListener("keypress", onKeyPress, false);

    function onKeyDown(e){
        var keyCode = e.keyCode;
        switch(keyCode){
            case 87: //w
                onKeyW();
            break;
            case 65: //a
                onKeyA();
            break;
            case 83: //s
                onKeyS();
            break;
            case 68: //d
                onKeyD();
            break;
        }



function onKeyW(){
    playerYPos -= 5;
}
function onKeyA(){
    playerXPos -= 5;
}
function onKeyS(){
    playerYPos += 5;
}
function onKeyD(){
    playerXPos += 5;
}
为什么要这样做?感谢您的帮助

编辑:作为旁注,我在使用布尔值之前已经这样做过(当按下w键时,
keyW
变量变为true,并且在mainGameLoop中有
if(keyW==true){playerYPos-=5;}

给你:

您不希望在每个关键点事件中更改位置。此外,还需要考虑帧之间的时间间隔。每帧添加任何静态量都会导致跳跃,因为一帧可能比上一帧晚30毫秒,也可能是60毫秒,这取决于许多因素

var playerXPos = 10;
var playerYPos = 10;
var playerSpeed = 0.3; // this is in pixels per ms

var aPressed = false;
var wPressed = false;
var sPressed = false;
var dPressed = false;
var lastTime = null;
function mainGameLoop(timestamp) {
    var delta = timestamp - (lastTime || timestamp);

    if(aPressed){
        playerXPos -= playerSpeed * delta;
    }
    if(dPressed){
        playerXPos += playerSpeed * delta;
    }
    if(wPressed){
        playerYPos -= playerSpeed * delta;
    }
    if(sPressed){
        playerYPos += playerSpeed * delta;
    }

    window.requestAnimationFrame(mainGameLoop);
    c = document.getElementById("gameCanvas").getContext("2d");

    c.clearRect(0, 0, 1000, 500);
    player();
    lastTime = timestamp;
}
window.requestAnimationFrame(mainGameLoop);

function player() {
    var playerImg = new Image();
    //playerImg.src = "knight.png";
    c.fillRect(playerXPos, playerYPos,100,100);
}

function onKeyW(pressed) {
    wPressed = pressed;
}

function onKeyA(pressed) {
    aPressed = pressed;
}

function onKeyS(pressed) {
    sPressed = pressed;
}

function onKeyD(pressed) {
    dPressed = pressed;
}

window.addEventListener("keydown", onKeyDown, false);

function onKeyDown(e) {
    var keyCode = e.keyCode;
    switch (keyCode) {
        case 87:
            //w
            onKeyW(true);
            console.log("bro");
            break;
        case 65:
            //a
            onKeyA(true);
            break;
        case 83:
            //s
            onKeyS(true);
            break;
        case 68:
            //d
            onKeyD(true);
            break;
    }
}

window.addEventListener("keyup", onKeyUp, false);

function onKeyUp(e) {
    var keyCode = e.keyCode;
    switch (keyCode) {
        case 87:
            //w
            onKeyW(false);
            console.log("bro");
            break;
        case 65:
            //a
            onKeyA(false);
            break;
        case 83:
            //s
            onKeyS(false);
            break;
        case 68:
            //d
            onKeyD(false);
            break;
    }
}

例如,您可能希望在游戏循环方法之外使用handleKeyboard()。此方法只需调用一次即可注册事件处理程序。
playerXPos+=5行可能会导致一些波动,因为它在一个相当大的跳跃时间内移动图像5px。我将其更改为1,但它仍然非常波动,只是速度较慢。您可以打开它以便人们可以尝试吗?将其移动到循环外也会有帮助:var c=document.getElementById(“gameCanvas”).getContext(“2d”);