如何将setTimeout与立即调用的函数一起正确使用

How to properly use setTimeout with immediately invoked function?

本文关键字:一起 函数 调用 setTimeout      更新时间:2023-09-26

我正在制作一个游戏,如果玩家在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);

所以我在敌人数组上使用了一个过滤函数,返回一个新数组,其中只包含还活着或只死了一段时间的敌人。

在"dead"answers"remove"之间创建延迟可以使用对象的"decay"属性来完成。您可以在每个游戏周期更新/增加此衰减属性的值。

// 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'
  }
});

使用反向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

这样,当你拼接时,你就在你身后拼接,而不是在你面前拼接。

您也可以像下面这样过滤数组。

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>

您可以简单地捕获实际的enemies[i]对象,而不是i,以便在完成验尸后将其从数组中正确删除,无论当时的索引是什么:

(function(e){
    setTimeout(function(){
        enemies.splice(enemies.indexOf(e), 1);
    }, 1000);
 })(enemies[i]);