Flash Game Dev Tip #4 – Bullet Manager Part 2

Tip #4 – Flixel – Bullet Manager Part 2

This tip follows-on from Tip #3, where we got a player controlled space-ship up, and had it fire all kinds of bullet death. In this tip we’re going to add something to use those bullets on – an Enemy manager, and a particle effect for when they are shot. By the end it’ll look like this:

Enemy Manager

As with the bullets in the previous tip we are going to create an Enemy Manager. This class will be responsible for creating a pool of enemies, launching them and recycling them when killed.

Our Enemy Manager works identically to the Bullet Manager from before. It starts by creating a pool of 100 enemies, which I admit is probably 90 more than we actually need at this stage of the game! Enemies are just extensions of an FlxSprite, and by default they have their exists value set to false, so they are free for allocation by the manager.

The manager overrides the flixel update function. All we do in there is check the value of the timer. getTimer() is a Flash utility class that gives you the number of milliseconds since the SWF started playing. It’s a really good way of timing things without having to use Timer Events, as it’s just integer based, fast and pretty accurate.

Our releaseRate is set to 500. That’s in milliseconds, so 500 would be every half a second (1000 ms per second). If enough time has elapsed we release a new enemy. This simply pull the next available enemy from the pool and call its launch function.

The enemy class looks like this:

We extend an FlxSprite but make two significant changes.

3, 2, 1, Launch!

The code in the Enemy launch function does two things. 1) It places the enemy at a random x coordinate, and just off the top of the screen, with a random x velocity. And 2) it resets its health to 4 and tells flixel it now exists.

By giving it 4 health it means it’ll take 4 shots to kill the alien.

We also override the kill function to give the player + 20 points to their score once the alien is dead.

The final small change is in the update function. If the alien flies off the bottom of the screen, we set its exists to false. If we didn’t do this it’d just carry on flying down into game space, where the player will never see it, and eventually our pool would run out of aliens to launch.


Our PlayState.as class has been expanded ever so slightly from last time. It now includes the enemies on the flixel display list, and the fx class which we’ll cover in a moment.

Crucially in the update function we run a collision check:

FlxU is the flixel general utilities class. And one of those utilities is called “overlap” which will tell us if any two objects are overlapping. The parameters you pass are the two objects to test and a function to call if the overlap is true.

You can pass in whole groups of objects, which is what we do in this case. We’re asking flixel to check all bullets in the bullets group, against all enemies in the enemies group. And if it finds an overlap from two “alive” (existing) objects it will call the bulletHitEnemy function inside the Enemy Manager class.

The code for this function can be seen above, but it works by taking the 2 objects as parameters (in the order in which you define them in the overlap call, so in our case bullet first and enemy second.

In this game bullets can only hit once. So we call

which will remove the bullet from the screen, and free it up ready for use again by the bullet manager.

The alien however is a little more robust. Remember we set it to have a health of 4? So when it gets shot we’ll “hurt” it by 1. Flixel objects have a hurt() method, which when called will reduce the objects health variable by the amount given:

In this instance we’ll “hurt” it by 1. Perhaps if the player was using super-bullets we could hurt it by 4, which would kill it instantly. Flixel will minus this amount from the health of the alien, and if its equal to zero it then calls kill on the object. As we over-rode the kill() method in Enemy.as we know the result of this is that the player gets 20 points added to their score.

After the bullet has been removed, and the alien hurt, we unleash a particle effect and increase the players score by 1. So for every bullet that hits an alien their score increases by 1, and a small particle shower happens.

The particle effect is controlled by the Fx class. When the alien is hit we call:

Our explodeBlock function takes 2 parameters, and x and a y value which it uses to control where to start the explosion effect.

Boom, shake the room

The Fx class is responsible for controlling our FlxEmitters. In the world of flixel these are objects capable of emitting a series of FlxSprites with pre-defined velocity, rotation and gravity. Basically, you can make pretty particle effects using them.

Our Fx class creates a pool of 40 FlxEmitters and puts them into an FlxGroup. Every emitter is the same.

It also creates one more emitter called jets. This is used to create the jets trail that comes from the back of the players space ship.

In the Fx class we over-ride the update function and use it to position the jets at the x/y coordinates of the player:

The +4 and +12 values are just to position the emitter into the correct place, so it looks like it is coming from the back of the ship rather than the top left (the default x/y origin).

As you can see, having access to the player via the Registry is extremely handy here (see Tip #1 if you don’t know what the Registry is)

The explodeBlock function is the one that launches the particle shower when an alien is shot. It’s extremely simple:

It just gets a new emitter from the pool (if there is one available), places it into the correct x/y location for where the bullet hit the alien, and starts it running. The true parameter tells the emitter this is an explosion, so all of the particles will be fired out at once rather than bursting continuously.


With just a few extra classes our game has now come on quite a way. We’ve got aliens that fly down at you, bullets that can blow them to shreds, a nice particle trail following the ship and a pretty explosion for when things go boom. All in very few lines of hopefully easy to follow code.

In the next tip I’ll make the enemies fire back at you, give you a health bar and a number of lives. We’ll then add a scrolling tilemap background to really elevate things.

Download the source code and SWF from the Flash Game Dev Tips Google Code Project page.

Posted on March 5th 2011 at 11:03 am by .
View more posts in Flash Game Dev Tips. Follow responses via the RSS 2.0 feed.

11 Responses

Leave a comment
  • jarkar
    March 17th 2011 at 6:20 pm

    Thanks. Great tuts!

    Just curious, what is the difference between:

    var enemy:Enemy = Enemy(getFirstAvail());


    var enemy = getFirstAvail();

    ..well actually Enemy(getFirstAvail()) is what i dont understand. How is that you can call getFirstAvail inside Enemy class?

  • March 17th 2011 at 11:04 pm

    var enemy:Enemy defines the data type of the variable. If you don’t specify the type, and have Strict mode on in flex, it’ll throw a warning when you compile. Plus it’s good practise! and allows FlashDevelop to give you context help.

    Enemy(…) is known as a cast. Basically I’m telling the compiler that what comes out of getFirstAvail() should be treated as the Enemy data type.

  • jarkar
    March 18th 2011 at 4:03 pm

    Thanks for answer Rich.

    I was thinking something like that.. syntax was confusing, and i didnt know what to tell the google :) For others who havnt use to that kind of syntax, this does the same thing:

    var enemy:Enemy = getFirstAvail() as Enemy;

  • March 18th 2011 at 4:32 pm

    Although they are similar, it’s the way errors are handled that are different. “getFirstAvail() as Enemy” will evaluate the result of getFirstAvail(), and if the result is of the data type Enemy, it will return it. Otherwise it will return null.

    Enemy(getFirstAvail()) will try to cast the result as an Enemy data type, regardless of what it actually is. Of course that conversion may not always succeed, and if it doesn’t it’ll throw a TypeError which you can handle. Just be careful to check the var before using it (don’t assume it’ll be what you asked it to be!)

  • jarkar
    March 19th 2011 at 5:36 pm

    hmm.. ok. Weird syntax make more sense for me now. I didnt even think it might have something to do with error handling.

  • Kevin Trepanier
    April 18th 2011 at 7:31 pm

    What if you have different kinds of enemies? Would you create an individual “EnemyManager” class extending FlxGroup for each kind of enemy or would there be a way to have all the enemies handled by the same class?

  • April 18th 2011 at 8:04 pm

    I would extend the EnemyManager so handle the different types of enemies. So I’d ask it to spawn say a “robot” or spawn an “invader” or a “mothership”, etc. If there were literally stacks of different enemy types then I’d find a way to classify them to stop this class getting overwhelming. For example maybe some are land-based vs. air-based, maybe they are level based. There’s usually a way to keep things sane :)

  • Kevin Trepanier
    April 20th 2011 at 6:56 pm

    I don’t quite get it.. Is it possible to add different kind of enemies inside a same FlxGroup and get the desired one out of it or should I have a unique FlxGroup for each enemy kind?

  • Kevin Trepanier
    April 20th 2011 at 7:16 pm

    Ah! Forget it, I found a useful answer on the Flixel forum (an answer by you actually. :))

    I’m still curious about how you would extend the EnemyManager class to handle different enemies though… My OOP skills are quite lacking.

  • April 20th 2011 at 9:23 pm

    Ok.. for the next instalment in this series I will cover spawning different types of baddies from the same FlxGroup :)

  • test84
    October 16th 2011 at 1:29 am

    Two questions:
    1- In pixels.getFirstAvail() code, where the returned pixel gets its exists to false?
    2- getFirstAvail seems depricated, so closest thing I could find to it is getFirstAvailable but it never works because none of enclosed items’ exist is set to false.

Make yourself heard