Turn Your Avoider Game into a Shoot-’Em-Up

by Michael James Williams on May 20, 2009 · 61 comments

in Avoider Game Extras,Tutorial

I’m getting a bit tired of running away from these enemies without having any means of defending myself.

Let’s blast them.

Snapshot_O06.png
Click to play. [Space] to shoot.

This tutorial is based on my avoider game tutorial. If you followed that, you’ll be able to add these new bullets to your existing game easily. If not, don’t worry about it — just download the base zip file; it contains all the files I’m going to be using.

Space Invaders Shooting

Let’s start with the simplest style of shooting: press space to fire a bullet upwards.

We might as well start by drawing the bullet. Open the FLA and create a new symbol of type Movie Clip (I’m sure you know the drill by now). Call it Bullet and export it for ActionScript with the same class name.

I’ve drawn this very simple shape for mine:

screenshot

This is zoomed in, of course! A rectangle would look fine.

Time for some code. Open AvoiderGame.as. The first thing we’re going to do is get it recognising the space bar.

Listening for the Space Bar

Remember, there are four places we need to change to allow the space bar to be recognised.

First, we need to define a new Boolean at the class level:

?View Code ACTIONSCRIPT3
22
23
24
25
26
public var downKeyIsBeingPressed:Boolean;
public var upKeyIsBeingPressed:Boolean;
public var leftKeyIsBeingPressed:Boolean;
public var rightKeyIsBeingPressed:Boolean;
public var spaceBarIsBeingPressed:Boolean;

Next, we have to set that Boolean to false in the constructor:

?View Code ACTIONSCRIPT3
43
44
45
46
47
downKeyIsBeingPressed = false;
upKeyIsBeingPressed = false;
leftKeyIsBeingPressed = false;
rightKeyIsBeingPressed = false;
spaceBarIsBeingPressed = false;

Finally, we have to set that boolean to either true or false in the onKeyPress() and onKeyRelease() functions. Here’s onKeyPress():

?View Code ACTIONSCRIPT3
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
public function onKeyPress( keyboardEvent:KeyboardEvent ):void
{
	if ( keyboardEvent.keyCode == Keyboard.DOWN )
	{
		downKeyIsBeingPressed = true;
	}
	else if ( keyboardEvent.keyCode == Keyboard.UP )
	{
		upKeyIsBeingPressed = true;
	}
	else if ( keyboardEvent.keyCode == Keyboard.LEFT )
	{
		leftKeyIsBeingPressed = true;
	}
	else if ( keyboardEvent.keyCode == Keyboard.RIGHT )
	{
		rightKeyIsBeingPressed = true;
	}
	else if ( keyboardEvent.keyCode == Keyboard.SPACE )
	{
		spaceBarIsBeingPressed = true;
	}
}

I’ll leave you to figure out the code for onKeyRelease().

OK, now we can detect the space bar, it’s time to make it do something. First, we can just make it create a new bullet. Move to the point in the onTick() function, after the avatar gets moved but before any collision detection takes place, and add these lines:

?View Code ACTIONSCRIPT3
166
167
168
169
170
171
172
if ( spaceBarIsBeingPressed )
{
	var newBullet = new Bullet();
	newBullet.x = avatar.x;
	newBullet.y = avatar.y;
	addChild( newBullet );
}
Snapshot_O01.png
Click to play

Well… it’s a start. If you hold down space, you can draw pictures. Er, let’s get those bullets moving.

Getting the Bullets Moving

We might as well copy the way the enemies move for this. Remember how that works?

  • All enemies are placed in an array, army
  • Every tick, we loop through that array and call moveABit() on each enemy
  • moveABit() changes the enemy’s position slightly (in my code, it just increases y)

So first we need a bullets array. Add public var bullets:Array; to the rest of the public variables, and put bullets = new Array(); in the constructor function, just as we did with army.

Next we need to push the new bullet we created in the code above into our new array:

?View Code ACTIONSCRIPT3
172
173
174
175
176
177
178
179
if ( spaceBarIsBeingPressed )
{
	var newBullet = new Bullet();
	newBullet.x = avatar.x;
	newBullet.y = avatar.y;
	addChild( newBullet );
	bullets.push( newBullet );
}

Great, now we have an array of bullets. Time to loop through them.

Looping Through the Bullets

I know a lot of people have difficulty with arrays. Just remember, they’re like a numbered list. We move through the list backwards because certain problems would occur if we didn’t.

Here’s the important part of the army loop:

?View Code ACTIONSCRIPT3
var i:int = army.length - 1;
var enemy:Enemy;
while ( i > -1 )
{
	enemy = army[i];
	enemy.moveABit();
	i = i - 1;
}

If there are ten enemies, they will take up army[0] through army[9], so we start at army[9] and keep going backwards through the list — that’s what i = i - 1 does. We only do this while the number of the enemy that we’re looking at is more than -1; army[-1] doesn’t refer to anything, so we’d get an error if we tried to use it.

Here’s the code we’ll use for the bullets:

?View Code ACTIONSCRIPT3
181
182
183
184
185
186
187
188
var j:int = bullets.length - 1;
var bullet:Bullet;
while ( j > -1 )
{
	bullet = bullets[j];
	bullet.moveABit();
	j = j - 1;
}

(I’ve put this after we create the new bullet, but before we do any collision detection.)

Note that I’m using j to move through this loop instead of i. You don’t have to do this; I just think it’s less confusing.

OK, just one more thing we need to do: create the bullet.moveABit() function. Because this code is so similar to the Enemy’s, I’m just going to paste it here for you to copy:

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package 
{
	import flash.display.MovieClip;
	public class Bullet extends MovieClip 
	{
		public var speed:Number;	//pixels moved per tick
 
		public function Bullet() 
		{
			speed = 3;
		}
 
		public function moveABit():void 
		{
			y = y - speed;
		}
	}
}

Save that as Bullet.as. Run the game now, and here’s what you’ll get:

Snapshot_O02.png
Click to play

That’s better, but we still need to build in collision detection, and slow down the rate of fire.

Bullet-Enemy Collision Detection

We’ve got lots of bullets and lots of enemies, and we need to check whether any bullet hits any enemy. How?

If you read my mini-series on collectibles, you’ll already know. If not, I recommend thinking about it before reading on.

The answer is nested loops.

Rather than checking all of the bullets against all of the enemies, we check all of the bullets against one of the enemies, and then check all of the bullets against the next enemy, then the next, and so on.

Here’s a simplified example:

?View Code ACTIONSCRIPT3
var i:int = army.length - 1;
var enemy:Enemy;
while ( i > -1 )
{
	enemy = army[i];
	enemy.moveABit();
	j = bullets.length - 1;
	while ( j > -1 )
	{
		bullet = bullets[j];
		//if bullet collides with enemy, destroy them both
		j = j - 1;
	}
	i = i - 1;
}

(Note: I haven’t written var j or var bullet because those are already defined earlier in the function.)

If that’s not clear, grab a piece of paper and a pencil and work through it, imagining that there are five enemies and three bullets, and bullet[1] is colliding with enemy[3].

OK, now we’ve got the basic idea, it’s time to actually plug this code into our existing enemy movement loop. Sure, we could write another loop just to handle enemy-bullet collisions, but that would be wasteful, and will slow things down.

So, here’s my existing enemy movement loop:

?View Code ACTIONSCRIPT3
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
var avatarHasBeenHit:Boolean = false;
var i:int = army.length - 1;
var enemy:Enemy;
while ( i > -1 )
{
	enemy = army[i];
	enemy.moveABit();
	if ( PixelPerfectCollisionDetection.isColliding( avatar, enemy, this, true ) ) 
	{
		gameTimer.stop();
		avatarHasBeenHit = true;
	}
	if ( enemy.y > 350 )
	{
		removeChild( enemy );
		army.splice( i, 1 );
	}
	i = i - 1;
}

…and here’s my first attempt at enemy-bullet collision detection:

?View Code ACTIONSCRIPT3
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
var avatarHasBeenHit:Boolean = false;
var i:int = army.length - 1;
var enemy:Enemy;
while ( i > -1 )
{
	enemy = army[i];
	enemy.moveABit();
	//new code starts here
	j = bullets.length - 1;
	while ( j > -1 )
	{
		bullet = bullets[j];
		if ( bullet.hitTestObject( enemy ) )
		{
			removeChild( enemy );
			army.splice( i, 1 );
			removeChild( bullet );
			bullets.splice( j, 1 );
		}
		j = j - 1;
	}
	//new code stops here
	if ( PixelPerfectCollisionDetection.isColliding( avatar, enemy, this, true ) ) 
	{
		gameTimer.stop();
		avatarHasBeenHit = true;
	}
	if ( enemy.y > 350 )
	{
		removeChild( enemy );
		army.splice( i, 1 );
	}
	i = i - 1;
}

(I’ve used hitTestObject(), even though it’s not very accurate, because it’s much faster than PixelPerfectCollisionDetection.)

This does actually work, the bullets destroy the enemies and themselves, but error messages appear in the Output panel. The problem is, after an enemy gets destroyed by a bullet (removing it from the screen and the array), we still try to use it in the following bit of code (checking for a collision with the avatar, and to see whether it’s moved off the bottom of the screen).

To get around this, we can use the same technique we used for the avatar — the avatarHasBeenHit boolean:

?View Code ACTIONSCRIPT3
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
var avatarHasBeenHit:Boolean = false;
var enemyHasBeenHit:Boolean;
var i:int = army.length - 1;
var enemy:Enemy;
while ( i > -1 )
{
	enemy = army[i];
	enemy.moveABit();
	enemyHasBeenHit = false;	//new code
	j = bullets.length - 1;
	while ( j > -1 )
	{
		bullet = bullets[j];
		if ( bullet.hitTestObject( enemy ) )
		{
			enemyHasBeenHit = true;		//new code
			removeChild( bullet );
			bullets.splice( j, 1 );
		}
		j = j - 1;
	}
	if ( enemyHasBeenHit )	//new code
	{						
		removeChild( enemy );	//new code
		army.splice( i, 1 );	//new code
	}
	else	//new code
	{
		if ( PixelPerfectCollisionDetection.isColliding( avatar, enemy, this, true ) ) 
		{
			gameTimer.stop();
			avatarHasBeenHit = true;
		}
		if ( enemy.y > 350 )
		{
			removeChild( enemy );
			army.splice( i, 1 );
		}
	}
	i = i - 1;
}

(I’ve written //new code throughout the code to make it easier to see what’s changed.)

So now we’re only checking for enemy-avatar collisions, and whether the enemy’s left the screen, if the enemy hasn’t already been hit by a bullet. It’s still not perfect, because we’ve got the same code in two separate parts of the loop (removing the enemy after it’s been hit by a bullet or left the screen) — can you see a way to improve that?

Check out the game so far:

Snapshot_O03.png
Click to play

Getting better!

Slowing Down the Rate of Fire

Does the constant stream of bullets look familiar to you?

screenshot

It’s actually the same problem we had way back in Part 2 of the base tutorial, when a new enemy was being created every tick.

Back then we fixed it by having a one-in-ten chance of an enemy being created each tick. But applying this same “random” approach to how often the player can fire is just going to be frustrating.

We need to make it more exact: the player can only shoot if at least ten ticks have passed since his last shot.

Hey, that’s basically an if statement! if ( ticksSinceLastShot >= 10 )

Let’s work that in. First, we’ll need a public var ticksSinceLastShot:int (remember, an int is just a whole number). Set ticksSinceLastShot = 0; in the AvoiderGame constructor function. Also, in the onTick() function, put:

?View Code ACTIONSCRIPT3
139
ticksSinceLastShot = ticksSinceLastShot + 1;

Now we can use our if statement from above:

?View Code ACTIONSCRIPT3
175
176
177
178
179
180
181
182
183
184
185
if ( spaceBarIsBeingPressed )
{
	if ( ticksSinceLastShot >= 10 )
	{
		var newBullet = new Bullet();
		newBullet.x = avatar.x;
		newBullet.y = avatar.y;
		addChild( newBullet );
		bullets.push( newBullet );
	}
}

Great! Try it out:

screenshot

…what? Oh! We need to reset the ticksSinceLastShot variable after we’ve, er, shot:

?View Code ACTIONSCRIPT3
175
176
177
178
179
180
181
182
183
184
185
186
if ( spaceBarIsBeingPressed )
{
	if ( ticksSinceLastShot >= 10 )
	{
		var newBullet = new Bullet();
		newBullet.x = avatar.x;
		newBullet.y = avatar.y;
		addChild( newBullet );
		bullets.push( newBullet );
		ticksSinceLastShot = 0;
	}
}

Try it out:

Snapshot_O05.png
Click to play

Excellent.

Odds and Ends

There are a few small changes I’d like to make, but I’ve covered them all in earlier tutorials so I won’t go into much detail.

First, for garbage collection purposes, we need to remove the bullets once they get above the top of the screen:

?View Code ACTIONSCRIPT3
188
189
190
191
192
193
194
195
196
197
198
199
200
var j:int = bullets.length - 1;
var bullet:Bullet;
while ( j > -1 )
{
	bullet = bullets[j];
	bullet.moveABit();
	if ( bullet.y < -10 )
	{
		removeChild( bullet );
		bullets.splice( j, 1 );
	}
	j = j - 1;
}

Second, I want to alter the scoring system, so that the player only gets points if he shoots an enemy. This means removing the points awarded when the enemy appears:

?View Code ACTIONSCRIPT3
141
142
143
144
145
146
147
148
149
if ( Math.random() < currentLevelData.enemySpawnRate )
{
	var randomX:Number = Math.random() * 400;
	var newEnemy:Enemy = new Enemy( randomX, -15 );
	army.push( newEnemy );
	addChild( newEnemy );
	//gameScore.addToValue( 10 );
	sfxSoundChannel = enemyAppearSound.play();
}

…and adding the score in the bullet-enemy collision detection:

?View Code ACTIONSCRIPT3
215
216
217
218
219
220
221
if ( bullet.hitTestObject( enemy ) )
{
	enemyHasBeenHit = true;		//new code
	removeChild( bullet );
	bullets.splice( j, 1 );
	gameScore.addToValue( 10 );
}

It might be a good idea to make the player lose points if an enemy gets past the bottom of the screen — but I’ll leave that up to you.

Third, I want to add more sound effects. For this, I’m going to use the awesome (and free!) tool sfxr:

sfxr, great free sound effects tool

I’ve used the Laser/Shoot setting to make the noise to be played when the player shoots, and the Explosion setting to be played when the bullet hits an enemy. (We’ll look at making explosion animations in a later tutorial.)

Here’s the result:

Snapshot_O06.png
Click to play

Wrapping Up

You can download a zip of all the files I used in this tutorial (including the sound files) from this link.

This small addition has changed the entire game. It’s very simple, though. Next time we’ll improve this, so that the player can aim before they fire.

Until then, why not try adding a different kind of bullet that can be fired with the shift key?

Click here to read the next part of this mini-series: Move with the Mouse, Aim with the Keyboard.

{ 60 comments… read them below or add one }

Richard July 30, 2010 at 3:20 pm

When I try that it comes up with this error

TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at AvoiderGame/onTick()
    at flash.utils::Timer/_timerDispatch()
    at flash.utils::Timer/tick()

Michael Williams August 21, 2010 at 12:18 am

Sorry about the late reply, Richard. Looks like your enemy var isn’t pointing to anything. But.. that can’t be the problem with the original code because you’ve just done a hitTestObject() check against it.

Hmm.

Are you getting any errors?

gta0004 September 9, 2010 at 5:02 am

Hey… when i do that the bullet doesnt seem to show up or move?

package 
{
    import flash.display.MovieClip;
    import flash.utils.Timer;
    import flash.events.TimerEvent;
    import flash.ui.Mouse;
    import flash.events.KeyboardEvent;
    import flash.ui.Keyboard;
    import flash.events.Event;

public class IntroGame extends MovieClip
{
    public var gameClock:Clock;
    public var army:Array;
    public var army2:Array;
    public var army3:Array;
    public var bullets:Array;
    public var enemy:Enemy;
    public var enemy2:Enemy2;
    public var enemy3:Enemy3;
    public var avatar:Avatar;
    public var gameTimer:Timer;
    public var ticksSinceLastShot:int;
    public var spaceBarIsBeingPressed:Boolean;

public function IntroGame()
{
    ticksSinceLastShot = 0;
    spaceBarIsBeingPressed = false;
    army = new Array();
    var newEnemy = new Enemy(-15,150);
    army.push( newEnemy );
    addChild( newEnemy );



    bullets = new Array();


    army2 = new Array();
    var newEnemy2 = new Enemy2(-15,150);
    army2.push( newEnemy2 );
    addChild( newEnemy2 );



    army3 = new Array();
    var newEnemy3 = new Enemy3(-15,50);
    army3.push( newEnemy3 );
    addChild( newEnemy3 );

    avatar = new Avatar();
    addChild( avatar );
    avatar.x = 650;
    avatar.y = 147;
    gameTimer = new Timer(25);
    gameTimer.addEventListener( TimerEvent.TIMER, onTick, false, 0, true );
    gameTimer.start();
}
public function onKeyPress( keyboardEvent:KeyboardEvent ):void
{
    if (keyboardEvent.keyCode == Keyboard.SPACE)
    {
        spaceBarIsBeingPressed = true;
    }
}
public function onKeyRelease( keyboardEvent:KeyboardEvent ):void
{
    if (keyboardEvent.keyCode == Keyboard.SPACE)
    {
        spaceBarIsBeingPressed = false;
    }
}
public function onTick( timerEvent:TimerEvent ):void
{
    ticksSinceLastShot = ticksSinceLastShot + 1;
    gameClock.addToValue( 50 );

    if (Math.random() &lt; 0.01)
    {
        var randomX:Number = Math.random() * 400;
        var newEnemy:Enemy = new Enemy(-15,150);
        army.push( newEnemy );
        addChild( newEnemy );
    }

    if (Math.random() &lt; 0.001)
    {
        var randomX:Number = Math.random() * 400;
        var newEnemy2:Enemy2 = new Enemy2(-15,150);
        army2.push( newEnemy2 );
        addChild( newEnemy2 );
    }

    if (Math.random() &lt; 0.0001)
    {
        var randomX:Number = Math.random() * 400;
        var newEnemy3:Enemy3 = new Enemy3(-15,50);
        army3.push( newEnemy3 );
        addChild( newEnemy3 );
    }
    if (spaceBarIsBeingPressed)
    {
        if (ticksSinceLastShot &gt;= 10)
        {
            var newBullet = new Bullet();
            newBullet.x = 650;
            newBullet.y = 150;
            addChild( newBullet );
            bullets.push( newBullet );
            ticksSinceLastShot = 0;

        }
    }
    var j:int = bullets.length - 1;
    var bullet:Bullet;
    while ( j &gt; -1 )
    {
        bullet = bullets[j];
        bullet.moveABit();
        if ( bullet.y &lt; -10 )
        {
            removeChild( bullet );
            bullets.splice( j, 1 );
        }
        j = j - 1;
    }
    var avatarHasBeenHit:Boolean = false;
    var enemyHasBeenHit:Boolean;
    var i:int = army.length - 1;
    var enemy:Enemy;
    while ( i &gt; -1 )
    {
        enemy = army[i];
        enemy.moveEnemy1();
        enemyHasBeenHit = false;
        j = bullets.length - 1;
        while ( j &gt; -1 )
        {
            bullet = bullets[j];
            if (bullet.hitTestObject(enemy))
            {
                enemyHasBeenHit = true;
                removeChild( bullet );
                bullets.splice( j, 1 );
                gameScore.addToValue( 10 );

            }
            j = j - 1;
        }
        if (enemyHasBeenHit)
        {
            removeChild( enemy );
            army.splice( i, 1 );
        }

        i = i - 1;

    }
}

}

}

can you check it out and see whats wrong please.
thanks

Michael Williams October 5, 2010 at 1:03 am

Hey gta0004,

Check out the debugging guide :)

Elle December 15, 2010 at 3:11 pm

Hey there. When I input in the var bullet j codings. I get errors shown below:

1120: Access of undefined property bullets. bullets.push( newBullet );
1119: Access of possibly undefined property length through a reference with static type int. var j:int = bullets.length – 1;
1061: Call to a possibly undefined method splice through a reference with static type int. bullets.splice (j, 1);
1119: Access of possibly undefined property length through a reference with static type int. j = bullets.length – 1;
1061: Call to a possibly undefined method splice through a reference with static type int. bullets.splice( j, 1 );

What’s wrong down here? Hope to hear from you soon

Calayston00 July 1, 2011 at 6:11 pm

First of all i must say that it’s one of the best tutorial ever!!!! But i don’t know if i’m gonna get an answer since the last post date from like last year :) But ok here I go anyway! I’ve been scracthing my head with an #2025 error for a while! I’m pretty sure it’s something ridiculous to solve. Here the problem : I’m using the same while loop in this tutorial but inside a function that i call in the loop function. But here is not the problem.

The problem is that i’ve put an empty MC on the stage and my Main class is tied to it. Then i call all my stuff. If i keep this structure no problem happen, the bullets hittest just well with the enemy. But for functionality reason (for a follow player func) I put almost all of my instances in an another Empty Mc that i declare from my main class. Everything works well but only one thing! when the bullet collide with the enemy. I get the #2025 error. What i do not understand is that when i do the fist while loop for the bullet I’ve added a code that test against a blocker Mc if you will and everything works well. It’s only when I check for bullet/enemy collision that the error popup! Here’s a little bit of my code to better understand :
(Don’t worry all my instance are nicely called and available for all my code)
Variable dec:

        //For Camera purpose
        public var contForCamera:MovieClip = new MovieClip();

    //variables and object declaration
    public var playerSpeed:Number=7;
    public var plife:Number=5;
    //declaring the main graphic container
    public var lv1:lv1_mc=new lv1_mc();
    public var blocker:blocker_mc=new blocker_mc();
    public var HUD:hud_mc = new hud_mc();
    public var harmZ01:harmZone= new harmZone();
    //adding the player
    public var radius:int=15; //determine by the size of the player
    public var player:player_mc=new player_mc();
    //Enemy
    public var army:Array = new Array();
    public var ghost:Ghost = new Ghost(200, 200);

Placing of my stuff :

            //placing objects
            blocker.alpha=20;
            HUD.x=10;
            HUD.y=10;
            harmZ01.x=150;
            harmZ01.y=300;
            harmZ01.alpha=.5;

        player.x=480;
        player.y=270;

    //adding the other object
    addChild(contForCamera);
    addChild(HUD);
    contForCamera.addChild(lv1);
    contForCamera.addChild(blocker);
    contForCamera.addChild(harmZ01);
    contForCamera.addChild(player);
    contForCamera.addChild(ghost);
    army.push(ghost);

Here’s the loop function :

        //Function for looping throught enemies and bullet for hittest!!!
        public function LoopForEnemiesAndBullet():void
        {
            //THIS CODE IS WORKING!!!!!!!!!!!!!!!!!!!!!!!
            var j:int = bullets.length-1;
            var bullet:Bullet;
            while (j > -1)
            {
                bullet = bullets[j];
                bullet.moveABit();
                if(blocker.hitTestPoint(bullet.x, bullet.y, true))
                {
                    removeChild(bullet);
                    bullets.splice(j,1);
                }
                j = j - 1;
            }
            //THIS ONE IS NOT WORKING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            var enemyHasBeenHit:Boolean;
            var i:int = army.length-1;
            var enemy:Ghost
            while (i > -1)
            {
                enemy = army[i];
                enemy.DetectWall(blocker);
                ghost.FollowPlayer(player);
                enemyHasBeenHit = false

            j = bullets.length -1;
            while (j > -1)
            {
                bullet = bullets[j];
                if(bullet.hitTestObject(enemy))
                {
                    enemyHasBeenHit = true;
                    removeChild(bullet);
                    bullets.splice(j,1);
                }
                j = j-1;
            }
            if(enemyHasBeenHit)
            {
                removeChild(enemy);
                army.splice(i, 1);
            }
            else
            {
                if(enemy.hitTestObject(player) && (invicible==false))
                {
                    plife -=1;
                    invicible=true;
                    InvicibleTimer.start();
                }
            }
            i = i - 1;
        }
    }

I’ve tried everything to contForCamera.removeChild(enemy); to root, to stage. I’m getting the same godamn #2025 error. If I remove the contForCamera MC and put everything on the same level everything works fine!!!! But i can say godbye to my followplayer function! (by the i use your other tut on activeTut for that! Nice! one!)

I’m sure it’s something stupid! But it’s been like 1 week i’ve been searching!
Thanks in advance for the help!

Calyston00 July 1, 2011 at 6:42 pm

Well, Well. You can flush my lengthy post just dound my error after following your nice DEBUGGING TUTORIAL!!!

The error was that i was call to many reference to the contForCamera.remove(X) thing. It’s was only require on this part of the code :

if(enemyHasBeenHit)
{
    contForCamera.removeChild(enemy); //HERE!!!
    army.splice(i, 1);
}

But thanks anyways to hear me rants!!!!

Michael James Williams July 4, 2011 at 3:15 pm

Ha, awesome, glad that helped :)

Pan Optik October 6, 2011 at 5:43 pm

Dear Michael,thank you for great tutorial.
I’m actually on the point of adding new arrays of enemies.
It works,but the new array has two strange behaviors:
1-copies are often placed in the same position at the same moment
2-it happens that hitting to some copies you hit the whole array which is present on the stage at the moment.
The only error which comes out is a 3596
cause i’ve actually duplicated the math random to addchild on stage

if ( Math.random() < currentLevelData.enemySpawnRate )

but using the same enemySpawnRate

i’m gonna checking out the guide for debugging,but i’ve posted this here anyway cause i think the method is not right.

ah and here the part connected with collisions..

var avatarHasBeenHit:Boolean = false;
            var enemyHasBeenHit:Boolean;
            var fenemyHasBeenHit:Boolean;
            var i:int = army.length - 1;
            var l:int = barmy.length - 1;

and further on…

while ( l > -1 )
            {
                fenemy = barmy[l];
                fenemy.moveABit();
                fenemyHasBeenHit = false;
                j = bullets.length - 1;
                while ( j > -1 )
                {
                    bullet = bullets[j];
                    if ( bullet.hitTestObject( fenemy ) )
                    {
                        fenemyHasBeenHit = true;
                        removeChild( bullet );
                        bullets.splice( j, 1 );
                        gameScore.addToValue( 10 );
                        sfxSoundChannel = explodeSound.play();
                    }
                    j = j - 1;
                }
                if ( enemyHasBeenHit )
                {
                    removeChild( fenemy );
                    barmy.splice( l, 1 );
                }
                else
                {
                    if ( PixelPerfectCollisionDetection.isColliding( avatar, fenemy, this, true ) ) 
                    {
                        gameTimer.stop();
                        avatarHasBeenHit = true;
                    }
                    if ( fenemy.y > 525 )
                    {
                        removeChild( fenemy );
                        barmy.splice( l,  1);
                    }
                    if ( fenemy.x < 310 )
                    {
                        removeChild( fenemy );
                        barmy.splice( l, 1 );
                    }
                    if ( fenemy.x > 560 )
                    {
                        removeChild( fenemy );
                        barmy.splice( l, 1 );
                    }
                }
                l = l - 1;
            }

thank you for reading and for eventual support!!

Pan Optik October 6, 2011 at 5:45 pm

and of course i have decleared the barmy and fenemy var in the public class..

Leave a Comment

Writing code? Write <pre> at the start and </pre> at the end to keep it looking neat.

Anti-Spam Protection by WP-SpamFree

{ 1 trackback }

Previous post:

Next post: