我为游戏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转换显示它正在移动?