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

24-更新渲染的重复周期

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

8.9.2 更新/渲染的重复周期

在任何一个应用状态中,都需要应用动画并对屏幕进行更新。从代码中分离出update()和render()函数来处理这些更新操作。例如,玩家飞船可以在游戏屏幕上移动,当玩家按下向上键时,屏幕上的飞船将推进,而不是静止。在之前的示例中,将所有更新飞船属性的代码和实际绘制飞船的代码全都包含在drawScreen()一个函数中。从例8-10开始,将摒弃简易的drawScreen()函数,用独立的update()函数和render()函数取而代之。将检测游戏专用按键的代码剥离出来,放入checkKeys()函数。

重新查看一下例8-8中的代码,这次将代码分解为几个函数,每个函数实现一个任务,如例8-10所示。

例8-10 分解为更新与渲染周期

function gameStatePlayLevel(){
  checkKeys();
  update();
  render();
}
function checkKeys(){
  //检查按键
  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;;
  }
}
function update(){
  x = x+movingX;
  y = y+movingY;
}
function render(){
  //绘制背景和文字
  context.fillStyle = '#000000';
  context.fillRect(0, 0, 200, 200);
  context.fillStyle = '#ffffff';
  context.font = '20px sans-serif';
  context.textBaseline = 'top';
  context.fillText ("render/update", 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() {
     runGame();
     window.setTimeout(gameLoop, intervalTime);
   }

为了节省篇幅,没有加入例8-9中的应用状态机的代码。在例8-10中仅简单展示了gameStatePlayLevel()函数的内容。

在8.10节中,当搭建完整程序时,将探讨更多的细节。