0
votes

I am creating a tower defense game and upon the aoe tower destroying 2 monsters at the same time i get 'TypeError: Error #1009: Cannot access a property or method of a null object reference...at Document/loop()... at EnemyRed/removeSelf()'

I am using Event.ENTER_FRAME function in the document class to check if (monster hp < 0), then call a function within the monster class to remove itself from its parent. (Code below).

The trace shows that it is trying to remove the same instance twice even though it should have been removed from the array already.

Document class:

public function loop(event:Event):void
    {

        //If enemy hit points < 0 remove self
        if(enemies.length > 0)
        {
            for(var e = 0; e < enemies.length; e++)
                {
                    if(enemies[e].hitPoints <= 0)
                    {
                        enemies[e].removeSelf();

Monster class:

public function removeSelf():void
    {
            trace(this.name);
            trace(this.parent);
            removeEventListener(Event.ENTER_FRAME, loop);
            parent.removeChild(this);
            Document.enemies.splice(this,1);
    }

trace returns:

Monster:  instance2019
Parent:  [object Level1]
Monster:  instance2019
Parent:  null
1

1 Answers

0
votes

It's been a while, but I think it should be

public function removeSelf():void {
  trace(this.name, this.parent);

  if (hasEventListener(Event.ENTER_FRAME)) {
    removeEventListener(Event.ENTER_FRAME, loop);
  }
  if (parent) {
    parent.removeChild(this);
  }
  var index:int = Document.enemies.indexOf(this);
  if (index > -1) {
    Document.enemies.splice(index,1);
  }
}

Now the instance should be removed properly.

Additionally, it's better to iterate the enemies array backwards, because when you are splicing an element out of an array while iterating forwards, the next items shift into previous positions, and the first of them doesn't get iterated through. If you are splicing the element while iterating backwards, the elements that change positions have already been processed within this loop, so no bug occurs. In this case the bug will just cause the 0-HP monsters to persist several frames before being removed out of the array, but other cases might even extend to breaking your game.

for(var e:int = enemies.length-1; e >=0; e--)
            {
                if(enemies[e].hitPoints <= 0)
                {
                    enemies[e].removeSelf();