1

I'm making a game where if the player hits the enemy from top, after 1 sec period,(that is to show dying animation), the enemy will splice out of the array.

It works fine while killing each enemy one by one, but when two enemies get killed at the same time, a problem occurs.

For example, if the enemies were in position 2 and 3 of the array when killed. After splicing it, the position 3 comes to position 2.
The second splice doesn't work as the position is already changed.

Is there a fix to this or a different method, or is my logic just plain invalid.

   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);
1
  • IMO You shouldnt use a setTimeout for this. I cannot tell if this is a browser/DOM based thing your doing, but if so I would advise using a transitional effect via css for this so that you dont delay the javascripts processing just for an effect. This will make your array accurate and you will not need this monkey patch Commented Jan 3, 2016 at 6:38

4 Answers 4

1

So what I did was use a filter function on the enemy array that returns a new array containing only enemies that are still alive, or have only been dead for a little while.

Creating a delay between 'dead' and 'remove' can be done with a 'decay' property on an object. You can update/increase the value of this decay-property on every game-tick.

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

Sign up to request clarification or add additional context in comments.

Comments

0

Use a reverse for loop.

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

That way, when you splice, you splice behind you instead of in front of you.

1 Comment

The timeout is necessary according to the logic i set, thats why it is getting the error. Without the timeout forward loop works as well.. And yeah even in reverse loop the problem still exists as the 'enemy' could be killed from any order
0

You could also filter the array like below.

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>

Comments

0

You could simply capture the actual enemies[i] object instead of i to remove it correctly from the array once the post-mortem dislay is done no matter what the index will be at that time:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.