0

I am making a game in JavaScript, and I am wondering how I can make objects move smoothly when you press the left and right key. So far, I've gotten a circle to move left and right. If you hold the right arrow key, the circle moves to the right, however, if you then press the left key at the same time it kind of glitches and stops moving, and vice versa. I want it so that when I press the right arrow key, and while still pressing it, I press the left key, the circle will go left, and vice versa. Anyhow, here is my code:

var x = 200;
draw = function() {
    background(255,255,255);
    ellipse(x, 200, 50, 50);
    if (keyIsPressed && keyCode === RIGHT){ //if right key pressed
            x += 5;
        }
        if (keyIsPressed && keyCode === LEFT){ //if left key pressed
            x -= 5;
        }
};
AbyxDev
  • 1,363
  • 16
  • 30
Mingdi
  • 1
  • 1
  • 1

2 Answers2

0

Usually, you would use the onkeydown and onkeyup events (see these four W3Schools pages). Then, you would switch to a 'left-moving mode' or 'right-moving mode' on the onkeydown event, and go back to 'stationary mode' on the onkeyup event (but only if the released key was the one responsible for the current mode. You wouldn't want to press left, press right, then release left and find the movement reset). For example:

// ---- Program logic ----

var x = 200;

var moveSpeedX = 0;
var moveSpeedXMultiplier = 5;

//Draw function would go here. Normal javascript doesn't support
//draw(), so this is only included in the Processing.js example below

var onRightArrowDown = function() {
    moveSpeedX = 1;
}

var onLeftArrowDown = function() {
    moveSpeedX = -1;
}

var onRightArrowUp = function() {
    if (moveSpeedX > 0) {
        moveSpeedX = 0;
    }
}

var onLeftArrowUp = function() {
    if (moveSpeedX < 0) {
        moveSpeedX = 0;
    }
}


// ---- Code to work with HTML keyboard events ----

document.addEventListener("keydown", function(e) {
    e = e || window.event; // For older browsers (uses window.event if e is undefined)

    if (e.keyCode === 37) { // left arrow
        onLeftArrowDown();
    }
    else if (e.keyCode === 39) { // right arrow
        onRightArrowDown();
    }
});

document.addEventListener("keyup", function(e) {
    if (e.KeyCode == 37) { // left arrow
        onLeftArrowUp();
    }
    else if (e.keyCode === 39) { // right arrow
        onRightArrowUp();
    }
});

(Some code adapted from answers to this question, particularly this one)

However, Khan-Academy uses a modification of JavaScript, which it refers to as 'ProcessingJS'. This appears to be similar to Processing.js, except that (from what I can tell) Processing.js is Processing code running on JavaScript, while ProcessingJS is JavaScript code that looks somewhat similar to Processing code. I'm not really sure about this, but I'll assume that ProcessingJS supports the same functions and variables as Processing.js.

Processing.js appears to support some key-related events, in the form of functions that are called automatically - similar to draw(). However, I can only find events that are called repeatedly when a key is held, not ones that only fire once. This makes the events/functions pretty useless here, so you may as well continue using global variables as you have been:

// ---- Program logic ----

var x = 200;

var moveSpeedX = 0;
var moveSpeedXMultiplier = 5;

draw = function() {
    background(255,255,255);
    ellipse(x, 200, 50, 50);

    callArrowKeyFunctions();

    x += moveSpeedX * moveSpeedXMultiplier;
};


var onRightArrowDown = function() {
    moveSpeedX = 1;
}

var onLeftArrowDown = function() {
    moveSpeedX = -1;
}

var onRightArrowUp = function() {
    if (moveSpeedX > 0) {
        moveSpeedX = 0;
    }
}

var onLeftArrowUp = function() {
    if (moveSpeedX < 0) {
        moveSpeedX = 0;
    }
}


// ---- Code to work with Processing.JS keyboard interface ----

var rightArrowPressedPrev = false;
var leftArrowPressedPrev = false;

var callArrowKeyFunctions = function() {

    if (keyIsPressed && keyCode === RIGHT && !rightArrowPressedPrev) {
        //if right key pressed, and it wasn't before
        onRightArrowDown();
    } else if (rightArrowPressedPrev {
        //if right key not pressed, but it was before
        onRightArrowUp();
    }

    if (keyIsPressed && keyCode === LEFT && !leftArrowPressedPrev) {
        //if left key pressed, and it wasn't before
        onLeftArrowDown();
    } else if (leftArrowPressedPrev) {
        //if left key not pressed, but it was before
        onLeftArrowUp();
    }


    rightArrowKeyPressedPrev = (keyIsPressed && keyCode === RIGHT);
    leftArrowKeyPressedPrev = (keyIsPressed && keyCode === LEFT);
    // &&, ==, etc aren't specific to if statements.
    // Instead, if statements can take any expression that returns a bool,
    // and these expressions can be used anywhere else as well.
}

It might be possible to generalise the callArrowKeyFunctions function to work with keys other than the arrow keys. However, the fact that keyCode === RIGHT and keyCode === LEFT can both return true at the same time (or maybe draw() is called twice) makes this difficult.

Community
  • 1
  • 1
NotEnoughData
  • 188
  • 3
  • 8
0

Use this piece

keyPressed = function(){
    keys[keyCode]=true;
};
keyReleased = function(){
    keys[keyCode]=false;
};

Then continue to use the keycodes of left and right, which I don't know, but a and d are

if(keys[65]){//a
    x-=5;
}
else if(keys[68]){//d
    x+=5;
}
bleh
  • 125
  • 2
  • 9