20-使用键盘控制玩家飞船
8.8.2 使用键盘控制玩家飞船
添加两个键盘事件和一个数组来保存每一个按键的按下状态。这样可以允许用户对一个键不间断地重复操作。街机游戏需要这种类型的按键响应方式。
1.用数组保存玩家按键
每一个键盘事件都对应一个keyCode,创建一个数组保存与每个keyCode对应的true或false的布尔值。用keyCode作为数组的索引来获取true或false的值。
var keyPressList = [];
2.键盘事件
为按下按键和释放按键创建独立的事件。在键盘的down事件中,首先取得事件的keyCode值,以这个值为索引,将keyPressList数组中对应的元素设为true。相反地,在键盘的up事件中将数组中对应的值设为false。
document.onkeydown = function(e){
e=e?e:window.event;
//ConsoleLog.log(e.keyCode + "down");
keyPressList[e.keyCode] = true;
}
document.onkeyup = function(e){
e = e?e:window.event;
//ConsoleLog.log(e.keyCode + "up");
keyPressList[e.keyCode] = false;
};
3.判断按键
游戏需要包含检查keyPressList中的值是否为真(或假)的代码,然后将结果应用于游戏逻辑。
if (keyPressList[38]==true){
//推进
var angleInRadians = player.rotation * Math.PI / 180;
facingX = Math.cos(angleInRadians);
facingY = Math.sin(angleInRadians);
movingX = movingX+thurstAcceleration*facingX;
movingY = movingY+thurstAcceleration*facingY;
}
if (keyPressList[37]==true){
//逆时针旋转
rotation-=rotationalVelocity;
}
if (keyPressList[39]==true){
//顺时针旋转
rotation+=rotationalVelocity;
}
将代码添加到当前的旋转示例中并进行测试。这里进行了一些重要的修改,例8-8展示了完整的HTML文件。
例8-8 控制玩家飞船
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ch8Ex8 - Ship turn with keys</title>
<script type="text/javascript">
window.addEventListener('load', eventWindowLoaded, false);
function eventWindowLoaded(){
canvasApp();
}
function canvasApp(){
var theCanvas = document.getElementById('canvas');
if (!theCanvas || !theCanvas.getContext){
return;
}
var context = theCanvas.getContext('2d');
if (!context){
return;
}
//canvasApp级变量
var rotation=0;
var x=50;
var y=50;
var facingX=0;
var facingY=0;
var movingX=0;
var movingY=0;
var width=20;
var height=20;
var rotationalVelocity=5; //每次飞船旋转多少度
var thrustAcceleration=.03;
var keyPressList=[];
function drawScreen(){
//检查按键
if (keyPressList[38]==true){
//推进
var angleInRadians = rotation * Math.PI / 180;
facingX=Math.cos(angleInRadians);
facingY=Math.sin(angleInRadians);
movingX=movingX+thrustAcceleration*facingX;
movingY=movingY+thrustAcceleration*facingY;
}
if (keyPressList[37]==true){
//逆时针旋转
rotation-=rotationalVelocity;
}
if (keyPressList[39]==true){
//顺时针旋转
rotation+=rotationalVelocity;;
} x=x+movingX;
y=y+movingY;
// 绘制背景和文字
context.fillStyle = '#000000';
context.fillRect(0, 0, 200, 200);
context.fillStyle = '#ffffff';
context.font = '20px sans-serif';
context.textBaseline = 'top';
context.fillText ("Player Ship - key turn", 0, 180);
//形状变换
var angleInRadians = rotation * Math.PI / 180;
context.save(); //将当前画布状态保存到栈中
context.setTransform(1,0,0,1,0,0); // 重置变换矩阵
//将画布原点平移到玩家飞船中心
context.translate(x+.5*width,y+.5*height);
context.rotate(angleInRadians);
//绘制飞船
context.strokeStyle = '#ffffff';
context.beginPath();
//将位置硬编码
//面向右边
context.moveTo(-10,-10);
context.lineTo(10,0);
context.moveTo(10,1);
context.lineTo(-10,10);
context.lineTo(1,1);
context.moveTo(1,-1);
context.lineTo(-10,-10);
context.stroke();
context.closePath();
//恢复上下文
context.restore(); //将旧的状态恢复到屏幕
}
var FRAME_RATE=40;
var intervalTime=1000/FRAME_RATE;
gameLoop();
function gameLoop() {
drawScreen();
window.setTimeout(gameLoop, intervalTime);
}
document.onkeydown=function(e){
e=e?e:window.event;
//ConsoleLog.log(e.keyCode + "down");
keyPressList[e.keyCode]=true;
}
document.onkeyup=function(e){
//document.body.onkeyup=function(e){
e=e?e:window.event;
//ConsoleLog.log(e.keyCode + "up");
keyPressList[e.keyCode]=false;
};
}
</script>
</head>
<body>
<div style="position: absolute; top: 50px; left: 50px;">
<canvas id="canvas" width="200" height="200">
Your browser does not support the HTML 5 Canvas.
</canvas>
</div>
</body>
</html>