I get this error and I think I understand it but I look at my code and the enemy does seem to be on the stage. The error is on the last line of the Enemy.as. It can't remove the enemy display object as it seems that the stage doesn't have it as a child.
Main.as (instantiates enemy:Enemy)
Enemy.as (holds the problem code) Basically it is saying that the stage doesn't hold the display object enemy.
I will post the parts where enemy is mentioned.
Main.as
private var enemy:Enemy = new Enemy(stage, hero);
...
for (var i:int=0; i< 5; i++)
{
enemy = new Enemy(stage, hero);
enemy.x = 100 + offsetEnemy;
enemyVector[i] = enemy;//populate the vector with enemies.
addChild(enemy);
enemy.cacheAsBitmap = true;
}
Enemy.as
package
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
import flash.display.Stage;
public class Enemy extends MovieClip
{
private var stageRef:Stage;
private var vy:Number = 1; //y velocity
private var ay:Number = .1; //y acceleration
private var target:Hero;
public function Enemy(stageRef:Stage, target:Hero) : void
{
this.stageRef = stageRef;
this.target = target;
x = Math.random() * stageRef.stageWidth;
y = -5;
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
private function loop(e:Event) : void
{
vy += ay;
y += vy;
if (y > stageRef.stageHeight)
removeSelf();
}
private function removeSelf() : void {
removeEventListener(Event.ENTER_FRAME, loop);
if (stageRef.contains(this))
stageRef.removeChild(this);
}
}
}
I have been testint with trace statements and it looks like it doesn't recognise my stageRef as stage. So I tried stage and that doesn't work either.
I did a trace on stage.stageHeight and got the error.
#1009: Cannot access a property or method of a null object reference
But it does recognise that in my Main.as. Why is this, I'm perplexed.
OK this works a lot better anyway as you don't have to name the parent.
parent.removeChild(this); It's more generic code.
BUT that damn stage.stageHeight still doesn't work in the Enemy class. So I have to put the code to make the enemy disappear in the Main.as which defeats the object of creating specific classes doesn't it?
If I add the enemy in the main class, then I would remove the enemy in the main class.
If you want the enemy to reference the stage, then you should use an ADDED_TO_STAGE event listener in the instantiation function and have its event handler deal with processing anything relative to the stage for that instance.
Don't use the same names for different instances of variables. You won't get anywhere assigning a variable to itself ('this' is most often unnecessary in AS3)...
this.stageRef = stageRef;
this.target = target;
Hi Ned.
I have read in quite a few areas now that it is quite normal to remove an object from it's own class ie: not in the Main.as class where it was instantiated. Basically because that code is specific to that object and belongs in that objects class just like all the other methods for that class.
parent.removeChild(this)
BTW: I do see the "this" keyword being used regularly even in adobe documentation as it's very useful not to have to write the same code for different objects.
parent.removeChild(this) can be used in a function
public function kill(this):void
{
parent.removeChild(this);
}
instead of
parent.removeChild(enemy)
parent.removeChild(star)
parent.removeChild(coin)
I hope I'm not annoying just trying to read my butt off and understand things. I ALWAYS appreciate your help and you are probably right anyway.
Cheers
North America
Europe, Middle East and Africa
Asia Pacific