开发者问题收集

如何正确地将 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