Help with hitTestObject and array

howdy all,

got internet now, so can get back on with research :wink:

but running into a strange thing on deleting an object from an array once it gets hit by a bullet it deletes both the bullet and the enemy

this is my for loop that does deal in the deletion. this is within my PlayState.hx - but was sure i had this made months ago, but weird its not working now. with the error below

thanks if you can help :wink:

for (b in 0 ... _arBullet.length){
			for (e in 0 ... _arEnemy.length) {
      	if (_arBullet[b].hitTestObject(_arEnemy[e])){
      	  removeChild(_arBullet[b]);
      	  _arBullet.splice(b, 1);
      	  removeChild(_arEnemy[e]);
      	  _arEnemy.splice(e, 1);
      	}
      }
    }

Uncaught exception - Invalid field access : hitTestObject

What platform target? What type is _arBullet? What does bullet extend?

targetting neko. _arBullet is an array that the player is firing. bullet extends sprite

Perhaps something is becoming Dynamic? Neko needs to know the type in order to access member methods

hmmm. ill have a check. just weird since i had the same thing done a while ago. cheers

This has nothing to do with the target you’re compiling to, or incorrect types. The problem is that you’re iterating forwards when you should be iterating backwards.

Let’s consider a simpler example:

var array:Array<String> = ["a", "b", "c", "d"];

for(i in 0...array.length) {
    if(i == 1) {
        array.splice(i, 1);
    } else {
        trace(array[i]);
    }
}

This code is meant to print “acd.” However, instead of doing that, it prints “ad” and then crashes. Can you see why?

Consider each iteration of the loop:

  1. i == 0, so the code prints “a.”
  2. i == 1, so the code removes index 1 from the array and doesn’t print anything. The array is now ["a", "c", "d"].
  3. i == 2, so the code prints “d.”
  4. i == 4, so the code crashes when it tries to read from the array.

See the problem? After splice() was called, the array got shorter, but the iterator wasn’t updated to reflect this. To make this algorithm work, you’d have to subtract 1 from both i and the iterator’s end value, but neither of those is allowed on an IntIterator instance.


Assuming you don’t care about order, here’s an easier solution.

var array:Array<String> = ["a", "b", "c", "d"];

var i:Int = array.length;
while(i-- > 0) { //Just for fun, you could type it as "i --> 0".
    if(i == 1) {
        array.splice(i, 1);
    } else {
        trace(array[i]);
    }
}

Output is dca, with no crash. The splice() call affects things at or above index i, but after that, the loop only looks at things below index i.


By the way, there’s a second bug in there that can be fixed by a continue statement. Can you figure out where?

1 Like

oooh homework. lovely.
thank you very much in explaining this, very clearly and very well. i can just see [just woke up] where i am going wrong and what i need to do.

this page is bookmarked for future use. :wink:

again, thank you ill be going through this again and again to make sure i completely get it, but it does make sense with how you have explained it

EDIT
and actually, you have introduced me to a new statement. i never knew about continue, so thats good, more to look up :wink: