requestAnimationFrame方法在2048游戏中是如何工作的?

时间:2016-03-30 16:32:49

标签: javascript css requestanimationframe

我为游戏2048找到了这个codepen.io:http://codepen.io/anon/pen/dMzmae

游戏是用JavaScript编写的,带有GameManager,HTMLActuator用于创建HTML元素,ScoreManager用于跟踪分数,KeyboardInputManager用于跟踪按下的内容和操作内容。

该应用程序使用window.requestAnimationFrame重绘窗口。我想知道它是怎么做到的。当代码启动时,它使用window.requestAnimationFrame()并在网格中的每个单元格中使用addTile()方法将每个tile添加到DOM。

 HTMLActuator.prototype.actuate = function (grid, metadata) {
      var self = this;

      window.requestAnimationFrame(function () {
        self.clearContainer(self.tileContainer);

        grid.cells.forEach(function (column) {
          column.forEach(function (cell) {
            if (cell) {
              self.addTile(cell);
            }
          });
        });

        self.updateScore(metadata.score);

        if (metadata.over) self.message(false); // You lose
        if (metadata.won) self.message(true); // You win!
      });
    };

如果你看一下addTime()方法,它也有一个window.requestAnimationFrame方法,如果它添加的tile有一个previousPosition属性,它会用currentPosition更新类:

   HTMLActuator.prototype.addTile = function (tile) {
      var self = this;

      var element   = document.createElement("div");
      var position  = tile.previousPosition || { x: tile.x, y: tile.y };
      positionClass = this.positionClass(position);

      // We can't use classlist because it somehow glitches when replacing classes
      var classes = ["tile", "tile-" + tile.value, positionClass];
     this.applyClasses(element, classes);

     element.textContent = tile.value;

      if (tile.previousPosition) {
        // Make sure that the tile gets rendered in the previous position first
        window.requestAnimationFrame(function () {
          classes[2] = self.positionClass({ x: tile.x, y: tile.y });
          self.applyClasses(element, classes); // Update the position
        });
      } else if (tile.mergedFrom) {
        classes.push("tile-merged");
        this.applyClasses(element, classes);

        // Render the tiles that merged
        tile.mergedFrom.forEach(function (merged) {
          self.addTile(merged);
        });
      } else {
        classes.push("tile-new");
        this.applyClasses(element, classes);
      }

      // Put the tile on the board
      this.tileContainer.appendChild(element);
    };

我想我想知道这个requestAnimationFrame在移动时如何正确显示切片?它使用网格中的切片信息构建每个切片。然后在addTile()中,它首先使用tile的previousPosition来构建一个曾经在棋盘上并为该位置创建一个类的tile,然后它检查该tile是否具有先前的位置并将该类更新回到tile的新位置在电网上。

但是,只有在具有前一个位置且在方法完成之前的tile的requestAnimationFrame方法中才会发生这种情况,并将该tile添加到DOM中的tile容器中。

我希望这个问题有道理。是否在原始window.RequestAnimationFrame调用HTMLActuator.prototype.actuate方法之后调用addTile方法()中嵌套的window.RequestAnimationFrame,以便在瞬间移动到新位置并且CSS转换显示它正在移动?

0 个答案:

没有答案