为什么坦克不能正常旋转?

时间:2012-05-20 04:51:06

标签: javascript html5 canvas rotation

我有一个移动坦克:http://www.exeneva.com/html5/movingTankExample/

坦克使用有限状态机来确定其面向的方向,默认设置为“向上”:

var tankDir = "up";

处理旋转的功能如下:

function dirTank(dir) {
  switch (dir) {
    case "up":
      if (tankDir == "right") {
        rotationAngle += -90;
      } else if (tankDir == "down") {
        rotationAngle += 180;
      } else if (tankDir == "left") {
        rotationAngle += 90;
      }
      break;
    case "down":
      if (tankDir == "up") {
        rotationAngle += 180; 
      } else if (tankDir == "right") {
        rotationAngle += 90;
      } else if (tankDir == "left") {
        rotationAngle += -90;
      }
      break;
    case "left":
      if (tankDir == "up") {
        rotationAngle += -90;
      } else if (tankDir == "right") {
        rotationAngle += 180;
      } else if (tankDir == "down") {
        rotationAngle += 90;
      }
      break;
    case "right":
      if (tankDir == "up") {
        rotationAngle += 90;
      } else if (tankDir == "down") {
        rotationAngle += -90;
      } else if (tankDir == "left") {
        rotationAngle += 180;
      }
      break;
  }
  tankDir = dir;
  rotationAngle %= 360;
}

drawScreen中的坦克渲染代码如下所示:

  // Draw the tank
  context.save();
  context.setTransform(1,0,0,1,0,0); // identity matrix
  context.translate(tankX + tileWidth/2, tankY + tileHeight/2);
  rotationAngle = rotationAngle * Math.PI/180;
  context.rotate(rotationAngle);
  context.drawImage(tileSheet, tankSourceX, tankSourceY, tileWidth, tileHeight, -tileWidth/2, -tileHeight/2, tileWidth, tileHeight);
  context.restore();

但坦克似乎转向然后突然恢复到原来的方向。有人可以帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:2)

rotationAngle应该保存在另一个变量中,所有的分配都应该更改为增加或减少当前角度,例如

rotationAngle += 90; // turn right
rotationAngle += 180; // reverse direction

完成这些更改后,您需要将角度标准化:

rotationAngle %= 360;

<强>更新

Make sure to not overwrite the `rotationAngle` later in the code when you convert from degrees to radians.

rotationAngle = rotationAngle * Math.PI/180;

应该成为:

rotationAngleRad = rotationAngle * Math.PI/180;

然后在rotationAngleRad来电中使用.rotate()

答案 1 :(得分:1)

原因是每次重绘画布时都需要更改旋转,而不仅仅是第一次。