starscape
starscape

Reputation: 2973

HTML5/Javascript - My user-triggered canvas animation choppy

I have a simple concept. When the player presses W, A, S, or D, an image on the canvas moves accordingly. However, this results in very choppy animation, and I'm not sure why(though I think it has something to do with my event listeners). Below is my code.

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;
}

Why is it doing this? Any help is appreciated!

EDIT: As a side note, I have done this before using booleans(when the w key is pressed a keyW variable becomes true, and in the mainGameLoop there is if(keyW == true){playerYPos -= 5;})

Jsfiddle

Upvotes: 2

Views: 692

Answers (1)

Paul Hoenecke
Paul Hoenecke

Reputation: 5060

Here you go: jsFiddle

You don't want to change the position each key event. Also, you need to take into account the time between frames. Adding any static amount per frame will always be jumpy, since one frame might be 30ms since the last or it might be 60ms, depending on many factors.

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;
    }
}

Upvotes: 1

Related Questions