2013-03-27 85 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; 

玩家可以預期按住按鈕(S)爲好。

回答

15

這是我通常這樣做的。首先你需要一個數組來保存關鍵狀態。

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 2013-03-27 17:02:01

+1

+1個不錯的演示; – 2013-03-27 17:09:11

+1

我應該反對它只是爲了不同。 :D – 2013-03-27 17:21:19

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

這個設置的好處是,它的行動直接與鍵關聯,允許你添加輕鬆實現更多按鍵操作,並且可以在運行時輕鬆添加/刪除按鍵,甚至可以在特定時間更改特定按鍵的功能,從而實現極大的靈活性。