addchild(enemy) returning null. Solved, final quick effeciency question

29 posts

Flag Post

What am I not understanding?


function die()
		{
			if (exploded == false)
			{
				var enemy = new EnemyShip();
				enemy.x = this.x;
				enemy.y = this.y;
				enemy.xSpeed = this.xSpeed;
				enemy.ySpeed = this.ySpeed;
				var enemy1 = new EnemyShip();
				enemy1.x = this.x;
				enemy1.y = this.y;
				enemy1.xSpeed = this.xSpeed * -1;
				enemy1.ySpeed = this.ySpeed * -1;
				var enemy2 = new EnemyShip();
				enemy2.x = this.x;
				enemy2.y = this.y;
				enemy2.xSpeed = this.xSpeed * 1;
				enemy2.ySpeed = this.ySpeed * -1;
				removeEventListener("enterFrame", enterFrame);
				stage.removeChild(this);
				Game.enemieskilled +=  1;
				exploded = true;
				if (Game.miniach == false)
				{
					Game.updateach("Achievement Unlocked: Mini Monster");
					Game.updateScore(1000);
					Game.miniach = true;
					Game.achMenu.mini.gotoAndStop(2);
				}
				if (Game.ship.ShieldPower == 1)
				{
					Game.updateScore(150);
				}
				if (Game.ship.ShieldPower == 2)
				{
					Game.updateScore(150*.7);
				}
				if (Game.ship.ShieldPower > 3)
				{
					Game.updateScore(150*1.3);
				}
				if (numberofenemies <= 1)
				{
					stage.addChild(enemy);// Error #1009: Cannot access a property or method of a null object reference.
				}
				if (numberofenemies > 1 && numberofenemies <= 2)
				{
					stage.addChild(enemy);// Error #1009: Cannot access a property or method of a null object reference.
					stage.addChild(enemy1);// Error #1009: Cannot access a property or method of a null object reference.
				}
				if (numberofenemies > 2 && numberofenemies <= 3)
				{
					stage.addChild(enemy);// Error #1009: Cannot access a property or method of a null object reference.
					stage.addChild(enemy1);// Error #1009: Cannot access a property or method of a null object reference.
					stage.addChild(enemy2);// Error #1009: Cannot access a property or method of a null object reference.
				}
				for (var i in Game.list)
				{
					if (Game.list[i] == this)
					{

						Game.list.splice(i,1);
					}
				}
			}
		}

 
Flag Post

It may or may not help to declare the “enemy” variables outside of the function.

In any case; there’s no need to have three different variables for enemy. You can reuse the same variable. In fact I would make a function for it.

var enemy:EnemyShip;
function createEnemy(a,b,m,n) {
	enemy = new EnemyShip();
	enemy.x = a;
	enemy.y = b;
	enemy.xSpeed = m;
	enemy.ySpeed = n;
	stage.addChild(enemy)
}
function die() {
	if (statement) {
		createEnemy(x,y,xSpeed,ySpeed)
	}
	if (statement) {
		createEnemy(x,y,xSpeed,ySpeed)
		createEnemy(x,y,xSpeed*-1,ySpeed*-1)
	}
	if (statement) {
		createEnemy(x,y,xSpeed,ySpeed)
		createEnemy(x,y,xSpeed*-1,ySpeed*-1)
		createEnemy(x,y,xSpeed,ySpeed*-1)
	}
}

(Writing “this.” is also unnecessary) ;)

 
Flag Post

- That static referencing creates spaghetti code.
- That you should not add DisplayObjects to the stage directly.
- That the stage property becomes available in your class after you add its object to the display list (but again, you should not add things to it).
- Probably what “stage” actually is.

 
Flag Post

I really like how thats much more compressed. I never understood how the (a,b,m,n) works before, but seeing it in the context of my code makes it very understandable. Unfortunately I still get the null error at the stage.addChild(enemy) , and then whenever I call createenemy (but thats due to addchld returning null so I guess its pretty much irrelevant)

 
Flag Post

I never add anything to the stage, except a movieclip that is the parent of all my other movieclips. And even then, I don’t use the prefix “stage.” I just say “addChild()”

An example of my code is below:

everythingHolder:MovieClip = new MovieClip();
enemyHolder:MovieClip = new MovieClip();

addChild(everythingHolder);
everythingHolder.addChild(enemyHolder)

enemyHolder.addChild(enemy)
 
Flag Post

I have almost everything added in my main class like im supposed to, I just havent been able to figure out how to add them upon the death of an enemyship at the enemy ships location. And If I add the createenemy function to the main class, then I havent been able to access it via my enemyship class when it dies

 
Flag Post

That’s what Events are for.

 
Flag Post

I usually call the event like function createenemy(e:Event) so how would I do that when there is the abmn in there?

 
Flag Post

I believe your problem is the stage.removeChild(this); line. Once you’ve removed this from the display list it no longer has access to stage, so any call to stage is going to generate an error.

 
Flag Post
Originally posted by Ace_Blue:

I believe your problem is the stage.removeChild(this); line. Once you’ve removed this from the display list it no longer has access to stage, so any call to stage is going to generate an error.

My code used to look like this and work perfectly fine.


if (exploded == false)
			{
				var enemy = new EnemyShip();
				enemy.x = this.x;
				enemy.y = this.y;
				enemy.xSpeed = this.xSpeed;
				enemy.ySpeed = this.ySpeed;
addchild(enemy)
				var enemy1 = new EnemyShip();
				enemy1.x = this.x;
				enemy1.y = this.y;
				enemy1.xSpeed = this.xSpeed * -1;
				enemy1.ySpeed = this.ySpeed * -1;
addchild(enemy1)
				var enemy2 = new EnemyShip();
				enemy2.x = this.x;
				enemy2.y = this.y;
				enemy2.xSpeed = this.xSpeed * 1;
				enemy2.ySpeed = this.ySpeed * -1;
addchild(enemy2)
				removeEventListener("enterFrame", enterFrame);
				stage.removeChild(this);
				Game.enemieskilled +=  1;
				exploded = true;
				if (Game.miniach == false)
				{
					Game.updateach("Achievement Unlocked: Mini Monster");
					Game.updateScore(1000);
					Game.miniach = true;
					Game.achMenu.mini.gotoAndStop(2);
				}
				if (Game.ship.ShieldPower == 1)
				{
					Game.updateScore(150);
				}
				if (Game.ship.ShieldPower == 2)
				{
					Game.updateScore(150*.7);
				}
				if (Game.ship.ShieldPower > 3)
				{
					Game.updateScore(150*1.3);
				}

But i decided I wanted it to be random the amount of enemies that spawned. Since I stopped calling addchild immidiatly after though, it stopped working.

 
Flag Post

In other words it used to be that after removing this from the display list you would no longer call on the stage’s properties and it worked fine. Then you added some references to methods of the stage (stage.addChild(whatever) in five or six places) and they all generated errors. It’s almost as if I am trying to point you in the right direction here.

<spoiler>Comment out the stage.removeChild(this); line and see if it works.</spoiler>
 
Flag Post
Originally posted by BluePriest:

I usually call the event like function createenemy(e:Event) so how would I do that when there is the abmn in there?

You communicate the death of a ship by dispatching an event if you want to notify another object about it.

 
Flag Post

ahh I seewhat you mean. I figured that since it was all in the same function order didn’t matter but you’re saying it does. at work now but ill give it a shot when I get home

 
Flag Post

Moving the removechild did it thank you Ace. So heres a final question. Is the way I was doing it, or the way DrYoshiYahu showed more effecient? Im guesing his is, but I want to make sure before I change all of my enemy classes.

 
Flag Post

Why do you have to “change all of your classes”?
You know why one extends classes?

 
Flag Post

I have 5 enemy ships. The Number 5 will spawn between 1-3 enemyship4s, the 4 will spawn between 1-3 enemyship3s, ect ect. Currently, all of them are using my old code before I did the random amount of enemies spawned.

 
Flag Post

The efficiency in that particular circumstance will only be a very very small difference. But at your current position in programming prowess; a good rule of thumb is that the less lines of code to do one task, the better.

It’s a really good excercise to help your development skills to look at a stack of code and see how much you can condense it down. I would suggest looking at all your enemy classes and seeing how similar they are. If they have a lot in common, try to merge them into one class in a similar way to what I just showed you.

I’ll show you another trick involving variables in functions:

enemy = new Enemy(x,y,xSpeed,ySpeed);
class Enemy extends MovieClip {
	public var xSpeed:Number;
	public var ySpeed:Number;
	public function Enemy(a:Number,b:Number,m:Number,n:Number) {
		x = a;
		y = b;
		xSpeed = m;
		ySpeed = n;
	}
}

This bit isn’t necessary, but I wanted to show you how to declare variables in the default function of a movieclip. It works the same way as before except that the function of the same name as the class is called automatically when a movieclip of that class is created.

 
Flag Post

All but 1 of my enemy classes are the exact same except the movieclip. Well, 1 of them is a little different. It has an explosion that is called instead of creating more enemies. Is there a way to condense those down? Like perhaps instead of extending a movieclip first, it extends something else, and then that code is applied to 4 different movieclips?

EDIT
Oh wait, some of them have a few different achievements attached to them as well. They each have an individual achievement for killing that enemy once.

 
Flag Post

To show how similar the classes are… http://pastebin.com/JCqa5dNZ http://pastebin.com/4vLqc3Mp are 2 that the only difference is 1 achievement. http://pastebin.com/YS1G0UMU is the one thats a bit different because thats when it finally dies instead of going to a smaller enemy

 
Flag Post

Simply use a variable that defines which enemy is which. If the only difference is the movieclip, what you can do is put all the enemies onto one movieclip on different frames, and use gotoAndStop to change the appearance based on which one it is.

enemy = new Enemy(1);
public var enemyType:Number;
public function Enemy(t:Number) {
enemyType = t;
gotoAndStop(enemyType)
if (health<=0) {
	if (enemyType == 1) {
		explode();
	}
	if (enemyType == 2) {
		spawnSmaller();
	}
}
 
Flag Post

^ I don’t recommend that method. Instead, use inheritance.

The enemy class hierarchy in my shooter was something like this: Sprite < GameObject < EnemyObject < [Specific Enemy Class]

- Sprite: You know what this is already.

- GameObject: Functions and properties for much anything that moves around on the gamefield—bullets, powerups, enemies, player, etc. Among the properties were things like appearance, hitbox definitions, and a function to be called by the game engine’s enter frame.

- EnemyObject: Additional properties for anything that is an enemy. This is where I put functions and properties that were common to MOST enemies—health, touch damage, shot damage, etc. Enemies that might do something differently, like exploding on death for example, would override the basic on-death function.

- [Specific Enemy Class]: This is where you’ll put things like specific appearances, health, damage, shot patterns, making one ship explode, another ship spawn babies, and yet another sprout a flag that says “BANG!” and fly away shortly after.

Inheritance is useful so that you’re not writing the same code over and over AND, should you decide to change something for all enemies across the board, you won’t have to go in and edit each one. Let’s say you wanted every enemy ship to leave smoke trails. You’d only have to edit the class that each ship extended once, not each ship individiually, over and over.

 
Flag Post
Originally posted by BluePriest:

All but 1 of my enemy classes are the exact same except the movieclip.

In this case, there should be only one class.

 
Flag Post

how intensive is the stretching and shrinking a movie clip? Because its the same movie clip, but different size?
@Aesica- IVe never done anything aside from classes extending a specific movieclip. How would the coding work for this? public class enemyclass extends ????? ? Im not sure what I would have it extend. And then have the specific enemy ships be public class enemyship5 extends enemyclass Im guessing that the specific enemies would extend the enemyclass.

 
Flag Post

Instead of appending “class” to the name, it’s quite common to have class names start with a capital letter.

If you are not sue what the base class is, I’d ask: What is your base class now? ;)

 
Flag Post

by base class I’m assuming you mean the class that adds the enemy ship to the stage. that would be my main game class. I was following Molly’s as3 shooter tutorial on Kong to start off my game. the game class is the base class of my whole game. I’m not sure if that’s what you’re talking about or not though