如何同步运行 requestAnimationFrame()?
How to run requestAnimationFrame() synchronously?
所以我正在制作一个类似俄罗斯方块的小游戏,其中的方块会相互掉落、被破坏等。我正在通过 requestAnimationFrame()
制作 HTML5 canvas 动画。调用此方法是为了收集悬在半空中的方块,并顺畅地落下:
function dropTiles() {
var tileArray = getFallingTiles();
function step() {
var finished = true;
for (var index = 0; index < tileArray.length; ++index) {
var currentTile = tileArray[index];
if (currentTile.fallDepth > 0) {
finished = false;
currentTile.erase();
currentTile.positionY -= 1;
currentTile.fallDepth -= 1;
currentTile.draw();
}
}
if (!finished) {
window.requestAnimationFrame(step);
}
}
window.requestAnimationFrame(step);
}
这是调用上述方法的主要方法:
function doGameEvents() {
setCanvasListeners(false);
do {
var comboFactor = 1;
dropTiles();
while (getGroups()) {
score();
dropTiles();
++comboFactor;
}
if (comboFactor == 1) {
var newTile = getRandomTile();
TILES.push(newTile);
dropTiles();
}
} while (!hasMoves());
setCanvasListeners(true);
}
一切正常,但我注意到一旦 dropTiles()
被调用,控制会立即转移到下一条指令,即使后者尚未完成(即 score()
仍然被调用悬在半空中)。
所以我的问题是:如何使 requestAnimationFrame()
同步并在控件退出我的 dropTiles()
方法之前完全完成?
你不知道。您将 drop 方法重写为 notify 当它完成时。最简单的:
function dropTiles(callback) {
//...
function step() {
//...
if (!finished) {
window.requestAnimationFrame(step);
}
else
{
if(callback)callback();
}
}
window.requestAnimationFrame(step);
}
所以现在当您调用 drop
时,您可以
drop(function(){
//this code runs when drop is finished
});
如果您需要等待很多 drop
才能完成,您可以选择使用 Promises。 (提示:Promise 就在这里……你真的应该学习如何使用它们)。
function dropTiles() {
return new Promise(function(resolve,reject){
//...
function step() {
//...
if (!finished) {
window.requestAnimationFrame(step);
}
else
{
resolve();
}
}
window.requestAnimationFrame(step);
});
}
现在您可以:
drop().then(function(){
//drop is finished
});
或
Promise.all([drop(), drop(), drop()]).then(function(){
//all the drops finished
});
所以我正在制作一个类似俄罗斯方块的小游戏,其中的方块会相互掉落、被破坏等。我正在通过 requestAnimationFrame()
制作 HTML5 canvas 动画。调用此方法是为了收集悬在半空中的方块,并顺畅地落下:
function dropTiles() {
var tileArray = getFallingTiles();
function step() {
var finished = true;
for (var index = 0; index < tileArray.length; ++index) {
var currentTile = tileArray[index];
if (currentTile.fallDepth > 0) {
finished = false;
currentTile.erase();
currentTile.positionY -= 1;
currentTile.fallDepth -= 1;
currentTile.draw();
}
}
if (!finished) {
window.requestAnimationFrame(step);
}
}
window.requestAnimationFrame(step);
}
这是调用上述方法的主要方法:
function doGameEvents() {
setCanvasListeners(false);
do {
var comboFactor = 1;
dropTiles();
while (getGroups()) {
score();
dropTiles();
++comboFactor;
}
if (comboFactor == 1) {
var newTile = getRandomTile();
TILES.push(newTile);
dropTiles();
}
} while (!hasMoves());
setCanvasListeners(true);
}
一切正常,但我注意到一旦 dropTiles()
被调用,控制会立即转移到下一条指令,即使后者尚未完成(即 score()
仍然被调用悬在半空中)。
所以我的问题是:如何使 requestAnimationFrame()
同步并在控件退出我的 dropTiles()
方法之前完全完成?
你不知道。您将 drop 方法重写为 notify 当它完成时。最简单的:
function dropTiles(callback) {
//...
function step() {
//...
if (!finished) {
window.requestAnimationFrame(step);
}
else
{
if(callback)callback();
}
}
window.requestAnimationFrame(step);
}
所以现在当您调用 drop
时,您可以
drop(function(){
//this code runs when drop is finished
});
如果您需要等待很多 drop
才能完成,您可以选择使用 Promises。 (提示:Promise 就在这里……你真的应该学习如何使用它们)。
function dropTiles() {
return new Promise(function(resolve,reject){
//...
function step() {
//...
if (!finished) {
window.requestAnimationFrame(step);
}
else
{
resolve();
}
}
window.requestAnimationFrame(step);
});
}
现在您可以:
drop().then(function(){
//drop is finished
});
或
Promise.all([drop(), drop(), drop()]).then(function(){
//all the drops finished
});