user2928768
user2928768

Reputation: 76

Multiple Jquery actions running at the same time

The example for this question is http://jsfiddle.net/4ac5u/

var x = 0;
var y = 0;
$(document).keydown(function(e){
    if (e.keyCode == 37) { 
       $("#left").css( "background-color", "red" );
       x = x-1;
       $("#ball").css( "margin-left", x*10 );
       return false;
    }
});
$(document).keyup(function(e){
    if (e.keyCode == 37) { 
       $("#left").css( "background-color", "#fff" );
       return false;
    }
});
$(document).keydown(function(e){
    if (e.keyCode == 38) { 
       $("#up").css( "background-color", "red" );
       y = y-1;
       $("#ball").css( "margin-top", y*10 );
       return false;
    }
});
$(document).keyup(function(e){
    if (e.keyCode == 38) { 
       $("#up").css( "background-color", "#fff" );
       return false;
    }
});
$(document).keydown(function(e){
    if (e.keyCode == 39) { 
       $("#right").css( "background-color", "red" );
       x = x+1;
       $("#ball").css( "margin-left", x*10 );
       return false;
    }
});
$(document).keyup(function(e){
    if (e.keyCode == 39) { 
       $("#right").css( "background-color", "#fff" );
       return false;
    }
});
$(document).keydown(function(e){
    if (e.keyCode == 40) { 
       $("#down").css( "background-color", "red" );
       y = y+1;
       $("#ball").css( "margin-top", y*10 );
       return false;
    }
});
$(document).keyup(function(e){
    if (e.keyCode == 40) { 
       $("#down").css( "background-color", "#fff" );
       return false;
    }
});

In this example I have different Jquery keydown listeners waiting for a specific key press, and on that keypress I want to move a ball in a certain direction (in this example using the css function to change the margin).

The issue is that you can only move in one direction at a time. Is it possible to have it so that if I have the down arrow and the right arrow down at the same time I move towards the bottom left part of the screen, not just right or down?

I have thought about possibly finding a way to alternate between them if both are pressed, but I'm not sure how that would work. Or if there is some way to do threading.

Also I'm not sure if there is a way to also make it not cancel out on pressing a new button while you are still holding the other down.

Upvotes: 0

Views: 146

Answers (4)

Abraham Hamidi
Abraham Hamidi

Reputation: 13789

Create an Array of Booleans (left, right, up, down) and on a setInterval check which ones are set to true

Here would be your updated code:

var x = 0;
var y = 0;
var keysDown = [false, false, false, false];
$(document).keydown(function (e) {
    switch (e.keyCode) {
        case 37:
            keysDown[0] = true;
            break;
        case 38:
            keysDown[2] = true;
            break;
        case 39:
            keysDown[1] = true;
            break;
        case 40:
            keysDown[3] = true;
            break;
    }
});
$(document).keyup(function (e) {
    switch (e.keyCode) {
        case 37:
            keysDown[0] = false;
            $("#left").css("background-color", "#fff");
            break;

        case 38:
            keysDown[2] = false;
            $("#up").css("background-color", "#fff");
            break;

        case 39:
            keysDown[1] = false;
            $("#right").css("background-color", "#fff");
            break;

        case 40:
            keysDown[3] = false;
            $("#down").css("background-color", "#fff");
            break;

    }
});

function checkBallMoving()
{
    if (keysDown[0] === true) {
        $("#left").css("background-color", "red");
        x = x - 1;
        $("#ball").css("margin-left", x * 10);
    }
    if (keysDown[1] === true) {
        $("#right").css("background-color", "red");
        x = x + 1;
        $("#ball").css("margin-left", x * 10);
    }
    if (keysDown[2] === true) {
        $("#up").css("background-color", "red");
        y = y - 1;
        $("#ball").css("margin-top", y * 10);
    }
    if (keysDown[3] === true) {
        $("#down").css("background-color", "red");
        y = y + 1;
        $("#ball").css("margin-top", y * 10);
    }
}
setInterval(function () {
    checkBallMoving();
}, 100);

DEMO

Upvotes: 0

Oleg
Oleg

Reputation: 23268

Please take a look at this code:

var x = 0;
var y = 0;
var dirs = {
    left: false,
    top: false,
    right: false,
    bottom: false
};
$(document).keydown(function(e){
  switch (e.keyCode) {
    case 37: dirs.left = true; return false;
    case 38: dirs.top = true; return false;
    case 39: dirs.right = true; return false;
    case 40: dirs.bottom = true; return false;
  }
});
$(document).keyup(function(e){
  switch (e.keyCode) {
    case 37: dirs.left = false; return false;
    case 38: dirs.top = false; return false;
    case 39: dirs.right = false; return false;
    case 40: dirs.bottom = false; return false;
  } 
});

var checkLeft = function() {
  if (dirs.left) {
    $("#left").css( "background-color", "red" );
    x--;
  } else {
    $("#left").css( "background-color", "#fff" );
  }
}

var checkRight = function() {
  if (dirs.right) {
    $("#right").css( "background-color", "red" );
    x++;
  } else {
    $("#right").css( "background-color", "#fff" );
  }
}

var checkTop = function() {
  if (dirs.top) {
    $("#up").css( "background-color", "red" );
    y--;
  } else {
    $("#up").css( "background-color", "#fff" );
  }
}

var checkBottom = function() {
  if (dirs.bottom) {
    $("#down").css( "background-color", "red" );
    y++;
  } else {
    $("#down").css( "background-color", "#fff" );
  }
}

var moveBall = function() {
  $("#ball").css({
    "margin-left": x*10,
    "margin-top": y*10
  });
}

setInterval(function() {
  checkLeft();
  checkRight();
  checkTop();
  checkBottom();

  moveBall()
}, 50);

http://jsfiddle.net/26XWw/

Upvotes: 1

Edgar Villegas Alvarado
Edgar Villegas Alvarado

Reputation: 18344

You can handle the keydowns in an array or object and then check for all the ones that were pressed:

Here you have:

Detect multiple keys on single keypress event in jQuery

Cheers

Upvotes: 0

Ivan
Ivan

Reputation: 10372

Combine all of your keydowns and keyups into one function with multiple if statements. Check for combinations first, and then check for single arrow presses. That should resolve the issue.

If you want to support users being able to move the ball around fluidly, I'd look into the example given here: http://jsfiddle.net/kzXek/. This example includes handling pressed down arrow keys to provide fluid movement.

// Made by RobseRob.dk
// Please give credit.
// Vars which contains key state
var movLeft = 0;
var movRight = 0;
var movUp = 0;
var movDown = 0;

var score = 0;
$(function() {
    // Keydown listener
    $("body").keydown(function(e) {
        ek = e.keyCode;
        if (ek==37) movLeft=1;
        if (ek==39) movRight=1;
        if (ek==38) movUp=1;
        if (ek==40) movDown=1;
    });
    // Keyuo listener
    $("body").keyup(function(e) {
        ek = e.keyCode;
        if (ek==37) movLeft=0;
        if (ek==39) movRight=0;
        if (ek==38) movUp=0;
        if (ek==40) movDown=0;
    });
});

Upvotes: 1

Related Questions