admin管理员组文章数量:1424942
So I'm making a small tetris like game where tiles fall on each other, get destroyed etc. I'm making HTML5 canvas animation through requestAnimationFrame()
. This method is called to gather tiles hanging in mid-air and drop them down smoothly:
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);
}
This is the main method where the above method is called from:
function doGameEvents() {
setCanvasListeners(false);
do {
var boFactor = 1;
dropTiles();
while (getGroups()) {
score();
dropTiles();
++boFactor;
}
if (boFactor == 1) {
var newTile = getRandomTile();
TILES.push(newTile);
dropTiles();
}
} while (!hasMoves());
setCanvasListeners(true);
}
Everything works okay but I noticed that once dropTiles()
is called the control gets immediately transferred to the next instruction, even if the latter is not yet finished (i.e. score()
is called with tiles still hanging in mid-air).
So my question is: how to make requestAnimationFrame()
synchronous and pletely finish before the control exits my dropTiles()
method?
So I'm making a small tetris like game where tiles fall on each other, get destroyed etc. I'm making HTML5 canvas animation through requestAnimationFrame()
. This method is called to gather tiles hanging in mid-air and drop them down smoothly:
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);
}
This is the main method where the above method is called from:
function doGameEvents() {
setCanvasListeners(false);
do {
var boFactor = 1;
dropTiles();
while (getGroups()) {
score();
dropTiles();
++boFactor;
}
if (boFactor == 1) {
var newTile = getRandomTile();
TILES.push(newTile);
dropTiles();
}
} while (!hasMoves());
setCanvasListeners(true);
}
Everything works okay but I noticed that once dropTiles()
is called the control gets immediately transferred to the next instruction, even if the latter is not yet finished (i.e. score()
is called with tiles still hanging in mid-air).
So my question is: how to make requestAnimationFrame()
synchronous and pletely finish before the control exits my dropTiles()
method?
1 Answer
Reset to default 8You don't. You rewrite your drop method to notify you when it is done. At its simplest:
function dropTiles(callback) {
//...
function step() {
//...
if (!finished) {
window.requestAnimationFrame(step);
}
else
{
if(callback)callback();
}
}
window.requestAnimationFrame(step);
}
So now when you call drop
, you can
drop(function(){
//this code runs when drop is finished
});
If you need to wait for many drop
s to finish, you might choose to use Promises instead. (hint: Promises are here to stay... you should really learn how to use them).
function dropTiles() {
return new Promise(function(resolve,reject){
//...
function step() {
//...
if (!finished) {
window.requestAnimationFrame(step);
}
else
{
resolve();
}
}
window.requestAnimationFrame(step);
});
}
Now you can:
drop().then(function(){
//drop is finished
});
or
Promise.all([drop(), drop(), drop()]).then(function(){
//all the drops finished
});
本文标签: javascriptHow to run requestAnimationFrame() synchronouslyStack Overflow
版权声明:本文标题:javascript - How to run requestAnimationFrame() synchronously? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745396361a2656833.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论