如何正确地将 setTimeout 与立即调用函数一起使用?
2016-01-03
651
我正在制作一款游戏,如果玩家从顶部击中敌人,经过 1 秒的时间(即显示死亡动画),敌人将从阵列中拼接出来。
当逐个杀死每个敌人时,它可以正常工作,但是当两个敌人同时被杀死时,就会出现问题。
例如,如果敌人在被杀死时位于阵列的位置 2 和 3。拼接后,位置 3 变为位置 2。
第二次拼接不起作用,因为位置已经改变。
是否有修复此问题的方法或其他方法,或者我的逻辑完全无效。
for (var i = 0; i < enemies.length; i++) {
var collWithPlayer= that.collisionCheck(enemies[i], player);
if (collWithPlayer == 't') { //kill enemies if collision is from top
enemies[i].state = 'dead';
player.velY = -((player.speed));
score.totalScore += 1000;
score.updateTotalScore();
//immediately-invoked function for retaining which enemy died
(function(i){
setTimeout(function() { //show squashed enemy for a brief moment then splice
enemies.splice(i, 1);
}, 1000);
})(i);
3个回答
所以我所做的是在敌人数组上使用过滤函数,该函数返回一个新数组,其中仅包含仍然活着或只死了一小会儿的敌人。
可以使用对象的“衰减”属性在“死亡”和“移除”之间创建延迟。您可以在每个游戏滴答声中更新/增加此衰减属性的值。
// inside a gametick loop
var enemyCollisions = [];
enemies = enemies.filter(function (item) {
collisionWithPlayer = that.collisionCheck(item, player);
if (collisionWithPlayer === 't') {
item.state = 'dead';
item.decay = 0;
enemyCollisions.push({
direction: collisionWithPlayer,
with: item
});
}
if (typeof item.decay === 'number') {
item.decay = item.decay + 1;
}
return (item.state !== 'dead' && item.decay > 62);
});
enemyCollisions.forEach(function (item) {
if (item.direction === 't') {
player.velY = -((player.speed));
score.totalScore += 1000;
score.updateTotalScore();
} else {
//TODO deal with collisions other then 't'
}
});
Norbert
2016-01-03
使用反向 for 循环。
for (var i = enemies.length; i--;){
// your stuff here
// hopefully the timeout isn't necessary, or this still has a chance of not working, considering race conditions
enemies.splice(i, 1);
}
// if it is, do the timeout outside of the for loop
这样,当您进行拼接时,您会在您身后进行拼接,而不是在您身前进行拼接。
Jason Suttles
2016-01-03
您还可以像下面这样过滤数组。
function myfunc(){
var enemies = [1,2,3,4,5];
var elementToRemove = 3;
enemies = enemies.filter(function(val){
return (val !== elementToRemove ? true : false);
},elementToRemove);
alert('[' + enemies.join(' , ') + ']');
}
<button id="btn" onclick="myfunc();">Go</button>
kurt
2016-01-03