2

我在画布的屏幕上渲染了瓷砖地图和坦克:

http://www.exeneva.com/html5/movingTankExample/

但是,您会注意到坦克的动画运动(移动轨迹)经常发生。你将如何改变它,以便坦克履带的移动仅在坦克移动时发生?请注意,目前没有物理学。

4

2 回答 2

1

您将必须实现一个state machine控制坦克实际状态的基础。

例如。

  1. 在 STOPPED 状态下,坦克没有动画,它以这个状态开始;
  2. 当您按下一个键时,您将状态切换为 MOVING,因此动画功能将使用此标志来知道何时为您的精灵设置动画;
  3. 当您释放一个键时,您将状态切换回 STOPPED。

看看这个链接(第二部分多为真实动作,第一部分更理论化):http ://active.tutsplus.com/tutorials/actionscript/the-power-of-finite-state-machines-概念与创造/

它是关于 Flash 的,但这个概念是通用的。

于 2012-05-20T01:06:51.817 回答
1

您的startUp函数drawScreen每 100 毫秒调用一次,其中坦克运动得到动画。您需要将动画逻辑提取drawScreen到它自己的函数中,例如animateMovement并从您的处理程序中调用它onkeydown。就像是:

function animateMovement(){
    var int = setInterval(function(){
        // Tank tiles
          var tankSourceX = Math.floor(animationFrames[frameIndex] % tilesPerRow) * tileWidth;
          var tankSourceY = Math.floor(animationFrames[frameIndex] / tilesPerRow) * tileHeight;    
          // Draw the tank
          context.drawImage(tileSheet, tankSourceX, tankSourceY, tileWidth, tileHeight, tankX, tankY, tileWidth, tileHeight);
          // Animation frames
          frameIndex += 1;
          if (frameIndex == animationFrames.length) {
            frameIndex = 0;
          }
    },100);
    setTimeout(function(){clearInterval(int);}, 1000);
}

把它放在你的drawScreen函数之前,然后在你调用之后从你的document.onkeydown处理程序中调用它drawScreen。显然,您还需要从drawScreen函数中删除动画代码:

function drawScreen() {
  // Tile map
  for (var rowCtr = 0; rowCtr < mapRows; rowCtr += 1) {
    for (var colCtr = 0; colCtr < mapCols; colCtr += 1) {
      var tileId = tileMap[rowCtr][colCtr] + mapIndexOffset;
      var sourceX = Math.floor(tileId % tilesPerRow) * tileWidth;
      var sourceY = Math.floor(tileId / tilesPerRow) * tileHeight;

      context.drawImage(tileSheet, sourceX, sourceY, tileWidth, 
        tileHeight, colCtr * tileWidth, rowCtr * tileHeight, tileWidth, tileHeight);
    }
  }
  /*tank animation was here*/
} 
​
于 2012-05-20T01:11:57.933 回答