2013-03-27 3 views
3

Используя что-то вроде:Как обрабатывать несколько нажатий клавиш с холстом

window.addEventListener("keydown", handleFn, true); 

Как бы я быть в состоянии обрабатывать несколько нажатий клавиш одновременно, для использования многопользовательского? Несколько человек будут использовать одну клавиатуру, так что одновременно будут нажаты клавиши Q и P для перемещения разных объектов на экране.

У меня еще нет ни одного keyup ручек, и если бы это было решено.

Логика у меня до сих пор что-то вроде:

if keydown == Q 
    paddle.left = true; 

... 

//game loop 
if paddle.left == true 
    paddle.x -= 1; 
    paddle.left = false; 

Игроки могут ожидать удерживать кнопку (ы), а также.

ответ

15

Так я обычно это делаю. Сначала вам нужен массив для хранения keystates.

var keys=[]; 

Затем настройте слушателей событий.

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

Что делает следующее: задается элемент в массиве как true, так и false, соответствующий этому коду клавиш.

Тогда вам просто нужно использовать некоторые условия, чтобы увидеть, что нажато, и что вы должны делать.

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

Ниже приведена демоверсия, в которой вы можете перемещаться и работать с несколькими нажатиями клавиш. Используйте wasd и клавиши со стрелками.

Live Demo

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

canvas.width = canvas.height = 300; 

var player1 = { 
    x: 50, 
    y: 150, 
    velY: 0, 
    velX: 0, 
    color: "blue" 
}, 
player2 = { 
    x: 250, 
    y: 150, 
    velY: 0, 
    velX: 0, 
    color: "red" 
}; 

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

function update() { 

    if (keys[38]) { 
     if (player1.velY > -speed) { 
      player1.velY--; 
     } 
    } 

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

    if (keys[87]) { 
     if (player2.velY > -speed) { 
      player2.velY--; 
     } 
    } 

    if (keys[83]) { 
     if (player2.velY < speed) { 
      player2.velY++; 
     } 
    } 
    if (keys[68]) { 
     if (player2.velX < speed) { 
      player2.velX++; 
     } 
    } 
    if (keys[65]) { 
     if (player2.velX > -speed) { 
      player2.velX--; 
     } 
    } 
    ctx.clearRect(0, 0, 300, 300); 
    updatePlayer(player1); 
    updatePlayer(player2); 
    setTimeout(update, 10); 
} 

function updatePlayer(player) { 
    player.velY *= friction; 
    player.y += player.velY; 
    player.velX *= friction; 
    player.x += player.velX; 

    if (player.x >= 295) { 
     player.x = 295; 
    } else if (player.x <= 5) { 
     player.x = 5; 
    } 

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

    ctx.fillStyle = player.color; 
    ctx.beginPath(); 
    ctx.arc(player.x, player.y, 5, 0, Math.PI * 2); 
    ctx.fill(); 
} 

update(); 

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

Я бы использовал хэш объекта вместо массива. – Shmiddty

+1

+1 приятная демонстрация;) –

+1

Я должен проголосовать за это просто, чтобы быть другим. : D –

2

Вы можете попробовать рисунок так:

(function game(){ 
    // canvas setup ... 

    // set up a "hash" of keycodes associated with whether or not they 
    // are pressed, and what should happen when they are pressed. 
    var keys = { 
     37:{down:false, action:function(){player1.velX--;}}, 
     38:{down:false, action:function(){player1.velY--;}}, 
     39:{down:false, action:function(){player1.velX++;}}, 
     40:{down:false, action:function(){player1.velY++;}}, 

     65:{down:false, action:function(){player2.velX--;}}, 
     68:{down:false, action:function(){player2.velX++;}}, 
     83:{down:false, action:function(){player2.velY++;}}, 
     87:{down:false, action:function(){player2.velY--;}}, 
    }; 

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

    (function update() { 
     ctx.clearRect(...); 

     for(var key in keys) 
      if(keys[key].down) 
       keys[key].action(); 

     // redraw players. 

     requestAnimationFrame(update); 
    })(); 
})(); 

Хорошая вещь об этой установки является то, что она связывает действия непосредственно с помощью кнопок, позволяет добавлять больше ключевых действий и обеспечивает большую гибкость с возможностью легко добавлять/удалять нажатия клавиш во время выполнения и даже изменять то, что делает конкретный ключ в любой момент времени.

Смежные вопросы