trace( "maybe this will work…" );

Flinteroids: An Advanced Flint Tutorial

Prev 1 2 3 4 5 6 7 8 Next

Flinteroids

The Flint Particle System has a vast assortment of built-in behaviors. Most of the time, you can accomplish your desired effect with these behaviors, but if you want to build something truly unique, you’re going to have to create your own customized behaviors. This tutorial will guide you through the process of creating custom Action/Initializer classes, using InitializerGroups to create different types of particles with a single Emitter, interacting with particles through keyboard input, and leveraging the advanced features of the Flint Particle System.

This tutorial assumes you have already delved into the Flint library and built a few of your own particle systems. If you’re new to Flint, you can learn about the basic Flint actions in A Visual Introduction to the Flint Particle System. Also be sure to check out the documentation page at the Flint Particles website.

In the spirit of creating highly customized particle systems, we’re going to be creating something rather unexpected with Flint: a rudimentary Asteroids clone. That’s right, with the right combination of custom behaviors, Flint can even be used as a gaming platform. Flint takes care of a lot of the basic game programming for us, including particle physics and collision handling. Here’s a sneak-peek at the final result:

Get Adobe Flash player


Use the arrow keys to move around and the spacebar to fire. Download the optional source files, and let’s get started…

Step 1: Set up an environment for our Asteroids clone.

  1. Open a new .fla. I called mine ‘Flinteroids.fla’.
  2. Add your Flint library to its classpath.
  3. Set the Document Class to ‘Flinteroids’.
  4. Define the ‘Flinteroids’ class by creating a new ActionScript file in the same directory as your .fla. Save this file as ‘Flinteroids.as’.

Step 2: Configure a basic Flint particle engine in ‘Flinteroids.as’. It should look like this:

package {

    import flash.display.*;
    import org.flintparticles.twoD.emitters.Emitter2D;
    import org.flintparticles.twoD.renderers.*;
   
    public class Flinteroids extends Sprite{

        public var gameEmitter:Emitter2D;
        public var renderer:DisplayObjectRenderer;

        public function Flinteroids(){
            initEngine();
        }
       
        public function initEngine():void{
            // initialize engine
            gameEmitter = new Emitter2D();
            renderer = new DisplayObjectRenderer();
            addChild(renderer);
            renderer.addEmitter(gameEmitter);
        }
   
    }
}

The game will be comprised of a ship, asteroids, and missiles. All of these will be defined as particles of the same particle system. To add different types of particles to a single Emitter, we’re going to use Flint’s built-in InitializerGroup. InitializerGroup is a special Initializer that applies an array of other Initializers to the emitter. By defining one InitializerGroup for the ship, another for the asteroids, and another for the missiles, we can choose which particles we want to add to the system by added/removing the corresponding InitializerGroup.

Step 3: Define an InitializerGroup for the ship. Add this function to your ‘Flinteroids.as’ file:

public function initShip():void{
    // Create initializers for the ship
    shipInitializer = new InitializerGroup();
   
    // Give the ship a graphic:
    // The graphic should be defined the .fla's library and exported as 'ShipIcon'
    shipInitializer.addInitializer(new ImageClass(ShipIcon));
   
    // The ship should start at the center of the stage
    shipInitializer.addInitializer(
            new Position(new PointZone(new Point(275, 200)))
    );
        // The ship should start pointing up, not left
    shipInitializer.addInitializer(
            new Rotation(-Math.PI/2, -Math.PI/2)
    );
   
    // Set the collision radius of the ship according to its graphic
    var shipBounds:Rectangle = new ShipIcon().getBounds(this);
    shipInitializer.addInitializer(
        new CollisionRadiusInit(Math.max(shipBounds.width, shipBounds.height)/2)
    );
}

The ‘initShip();’ function defines the ship particle by adding Initializers for its DisplayObject, position, rotation, and collision radius. It assigns the InitializerGroup to a variable called ’shipInitializer’. We’ll need this reference in order to add the InitializerGroup to the Emitter, which we’ll do next.

Step 4: Add the ship to the emitter.

public function addShip():void{
    gameEmitter.addInitializer(shipInitializer);
    gameEmitter.counter = new Blast(1);
    gameEmitter.start();
    gameEmitter.removeInitializer(shipInitializer);
    // We'll want a reference to the ship for later.
    // This assumes that the ship was the first particle added
    // to the system.
    ship = gameEmitter.particles[0];
}

The function ‘addShip();’ adds the ship to the particle system by:

  1. Adding the InitializerGroup defining the ship to the emitter.
  2. Setting the emitter’s counter to a ‘Blast’ counter that outputs a single particle.
  3. Calling ‘gameEmitter.start();’ to add that particle to the system.
  4. Removing the InitializerGroup from the emitter. This is important: if you leave the InitializerGroup in the emitter, all subsequent ’start();’ calls will produce particles with ship-like properties.

It also records a reference to the particle that was created in the ’ship’ variable.

Compile time! You’ll have to add a few more imports and variables to the class, as well as the two new functions to the constructor. This is what the entire ‘Flinteroids.as’ should look like:

package {

    import flash.display.*;
    import flash.geom.*;
    import org.flintparticles.common.initializers.*;
    import org.flintparticles.common.counters.Blast;
    import org.flintparticles.twoD.emitters.Emitter2D;
    import org.flintparticles.twoD.renderers.*;
    import org.flintparticles.twoD.initializers.*;
    import org.flintparticles.twoD.particles.Particle2D;
    import org.flintparticles.twoD.zones.*;
   
    public class Flinteroids extends Sprite{

        public var gameEmitter:Emitter2D;
        public var renderer:DisplayObjectRenderer;
        public var shipInitializer:InitializerGroup;
        public var ship:Particle2D;

        public function Flinteroids(){
            initEngine();
            initShip();
            addShip();
        }
       
        public function initEngine():void{
            // Initialize the engine
            gameEmitter = new Emitter2D();
            renderer = new DisplayObjectRenderer();
            addChild(renderer);
            renderer.addEmitter(gameEmitter);
        }
       
        public function initShip():void{
            // Create initializers for the ship
            shipInitializer = new InitializerGroup();
           
            // Give the ship a graphic:
            // The graphic should be defined the .fla's library and
            // exported as 'ShipIcon'
            shipInitializer.addInitializer(new ImageClass(ShipIcon));
           
            // The ship should start at the center of the stage
            shipInitializer.addInitializer(
                    new Position(new PointZone(new Point(275, 200)))
                );
           
            // The ship should start pointing up, not left
            shipInitializer.addInitializer(
                    new Rotation(-Math.PI/2, -Math.PI/2)
                );
           
            // Set the collision radius of the ship according to its graphic
            var shipBounds:Rectangle = new ShipIcon().getBounds(this);
            shipInitializer.addInitializer(
                    new CollisionRadiusInit(
                        Math.max(shipBounds.width,
                                  shipBounds.height)/2)
                );
        }

        public function addShip():void{
            gameEmitter.addInitializer(shipInitializer);
            gameEmitter.counter = new Blast(1);
            gameEmitter.start();
            gameEmitter.removeInitializer(shipInitializer);

                        // We'll want a reference to the ship for later.
            // This assumes that the ship was the first particle added
            // to the system.
            ship = gameEmitter.particles[0];
        }
   
    }
}

You should get a SWF that looks something like the following. If your ship is pointed the wrong way, make sure it is defined in your .fla as pointing to the right. Otherwise, your ship is going to be firing missiles in the wrong direction, and that’s dangerous. Also make sure that it is centered about the origin, unless you want it to rotate awkwardly in the next section.

FlintAdvanced1

Ok, well that’s great. All that work for a measly little triangle on the screen? Don’t worry, we’re about to add some interactivity…

Prev 1 2 3 4 5 6 7 8 Next

December 18th, 2009 at 7:37 pm

Posted in Flash, Particle Systems

10 Responses to 'Flinteroids: An Advanced Flint Tutorial'

Subscribe to comments with RSS or TrackBack to 'Flinteroids: An Advanced Flint Tutorial'.

  1. Great article, Ryan. I’ve added a link from Flint’s documentation page.

    Richard Lord

    16 Jan 10 at 6:45 am

  2. Thanks!

    Ryan

    16 Jan 10 at 5:22 pm

  3. Great article indeed, I can’t wait to start using flint.

    One quick question, does flint support CCD?

    Oliver

    11 Mar 10 at 6:14 pm

  4. I’m not entirely sure. I do know that his algorithm is optimized for particles in motion, but I don’t know if continuous collision detection is supported. You should check with Richard Lord (The author of Flint Particles). He is a few posts above.

    Ryan

    12 Mar 10 at 7:37 pm

  5. [...] while back I had some spare time and decided to check out Flint and followed the Flinteroids tutorial. It’s cool but I extended it a little with a few extra effects and a High [...]

  6. I want to say thanks, I had never programmed before and had to use flashdevelop but you made it easy to follow and explained some great concepts difficult to find in beginner tutorials.

    You can find what I did at http://www.kongregate.com/games/ishlilith/circles-circling-circle

    ishlilith

    3 May 10 at 7:22 pm

  7. I like web design a lot. Your website is awesome. Do you guys know any good web classes that I can take?

    Herschel Dorce

    16 May 10 at 9:17 pm

  8. @ishlilith

    I really liked what you did with Flint. It’s counter-intuitive, but in a good way. Keep it up!

    Ryan

    Ryan

    25 May 10 at 2:33 am

  9. Hi Ryan, it seems there is a little mistake on page 7 -
    code for step 13 and step 14 identical.

    Bo

    22 Aug 10 at 1:19 am

  10. Sorry I mean step 12 and 13

    Bo

    22 Aug 10 at 1:21 am

Leave a Reply