当前位置:嗨网首页>书籍在线阅读

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>