SianLoong
SianLoong

Reputation: 3

AS3 Error #1004 occur when removeChild() in stage

//Main Class
package{
  public class Main extends MovieClip{
    private var bombCarrier:BombCarrier;
    private var building:Building;
    private var bomb:Bomb;
    public var buildingArray:Array;

    public function Main(){
      bombCarrier = new Carrier();
      addChild(bombCarrier);
      for(var i:int=0;i<5;i++){
        var xPosition:Number = i*105;
        building = new Building(xPosition, stage.stageHeight);
    addChild(building);
    buildingArray.push(building);
  }
      stage.addEventListener(Event.KeyboardEvent, keyDownFunction);
    }
    public function keyDownFunction(event:KeyboardEvent){
      if(event.keyCode == 70){
        bomb = new Bomb(bombCarrier.x, bombCarrier.y, 0.5);
        addChild(bomb);
      }
    }
  }
}

//Bomb Class
package{
  public class Bomb extends MovieClip{
    private var speed:Number;
    public function Bomb(x, y, speed){
      this.x = x;
      this.y = y;
      this.speed = speed;
      addEventListener(Event.ENTER_FRAME, loop);
    }
    public function loop(event:Event){
      this.y += speed;
      for(var i:int=0;i<Main(parent).buildingArray.length;i++){
        if(hitTestObject(Main(parent).buildingArray[i])){
          this.removeEventListener(Event.ENTER_FRAME, loop);
          Main(parent).buildingArray.splice(i, 1);
          parent.removeChild(this); //This line got Error
        }
      }
    }
  }
}

I try many approach, but i still get the same error which is TypeError: Error #1009: Cannot access a property or method of a null object reference. at Bomb/loop(). I already try to debug with command line by line, it seem to be just this line of code "parent.removeChild(this);" showing the problem.

Upvotes: 0

Views: 302

Answers (1)

BadFeelingAboutThis
BadFeelingAboutThis

Reputation: 14406

It looks like your trying to remove your bomb multiple times (in a for loop). So after the first time, it no longer is a child of the parent.

Also, you start your enter frame handler before you're bomb has been added to the stage, so parent will be null until that time.

Your going to want to break; out of your loop once you've removed the bomb the first time.

//Bomb Class
package{
  public class Bomb extends MovieClip{
    private var speed:Number;
    private var buildingArray:Array;

    public function Bomb(x, y, speed){
      this.x = x;
      this.y = y;
      this.speed = speed;
      addEventListener(Event.ADDED_TO_STAGE,addedToStage,false,0,true);
    }

    private function addedToStage(e:Event):void {
        buildingArray = Main(parent).buildingArray;  //it would be better to just pass it in the constructor
        addEventListener(Event.ENTER_FRAME, loop);
    }

    public function loop(event:Event){
      this.y += speed;
      for(var i:int=0;i<buildingArray.length;i++){
        if(hitTestObject(buildingArray[i])){
          this.removeEventListener(Event.ENTER_FRAME, loop);
          buildingArray.splice(i, 1);
          parent.removeChild(this);
          break; //get out of the loop
        }
      }
    }
  }
}

On an efficiency note, it would be faster if you held a reference to buildingArray in your bomb class so you don't have to do Main(parent). everytime you need to access it.

Upvotes: 1

Related Questions