2013-03-27 42 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); 
    })(); 
})(); 

这个设置的好处是,它的行动直接与键关联,允许你添加轻松实现更多按键操作,并且可以在运行时轻松添加/删除按键,甚至可以在特定时间更改特定按键的功能,从而实现极大的灵活性。