I decided to post a tutorial explaining how to use the classes I mentioned in this post. It won’t be a complete game, but it covers how Flixel uses animation, collision, tilemaps, and particle emitters.
**EDIT** It is important to note that this version of Flixel is 1.25. It may not be compatible with the current Flixel version. As I write this, 1.52 is current, but it has been changing rapidly lately.
If you haven’t already installed FlashDevelop and Flixel, you can get FlashDevelop here, and Emanuele Feronato has a post about installing and running Flixel here.
Once you have Flixel working and you can run the Mode demo project that comes with the installation of Flixel, you’ll want to make a new Flixel project. So in FlashDevelop: Project->New Project, select AS3 Project template, give the project a name (FlixelTutorial), and check the “Create directory for project” box.
In the Mode demo’s “src” folder, you should see a “com” folder. Copy that “com” folder into your new “src” folder. Now you have an empty Flixel project. (There is also a folder named “Mode” somewhere in there you can delete if you want, but it won’t mess up your project if you leave it alone).
There is one final step before we start coding. Assets. I’ve created a few simple sprites and a .txt file you’ll want to get, so we can have visuals in our program. Grab these and stick them in a new folder called “data” inside of your “src” folder. Now on to the actual code! DOWNLOAD -> Assets
We’ll be writing three actionscript files: Main.as, Gamestate.as, and Player.as, and we’ll be starting with Main.as. FlashDevelop already gives us a Main.as, so we’ll be replacing that file with our own. I’m putting the other two files inside the “com” folder inside another folder labeled “game” — so inside of your “src”->”com” you should have both an “adamatomic” folder and your new “game” folder. You can organize your files however you’d like, but you’ll need to change the naming of the packages in the example code if you want the program to run.
Here is our new Main.as file:
1 2 3 4 5 6 7 8 9 10 11 12 13 | package { import com.game.GameState; import com.adamatomic.flixel.*; [SWF(width = "288", height = "204", backgroundColor = "#000000")] public class Main extends FlxGame { public function Main():void { super(288, 204, GameState, 2, 0x000000, false); } } } |
Lines 3-4: We’re importing the GameState that we haven’t written yet and Adam’s Flixel libraries.
Line 5: Setting the window width, height, and color.
Line 6: We’re declaring the class. In Flixel you want to make sure your base game extends the FlxGame class.
Line 10: The super function we’re calling here is allowing us to pass in variables to the FlxGame’s constructor. These define some basic settings of the game:
1. width
2. height
3. What class to point to when the game begins(a play state, or perhaps a menu)
4. How much we should magnify each pixel. We’re doubling the size of each pixel by passing in “2″.
There are other parameters outlined in the FlxGame class, but we won’t be needing those in this tutorial.
5. The default background color.
6. “false” to say that we don’t want to display the big Flixel “F” at the beginning of the program.
Next we’re going to write the Player.as file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | package com.game { import com.adamatomic.flixel.*; public class Player extends FlxSprite { [Embed(source = "../../data/whiteguy.png")] private var PlayerImage:Class; public var decisionCounter:Number; public var decisionGoal:Number; public var decision:Number; public function Player(X:Number = 0, Y:Number = 0):void { super(PlayerImage, X, Y, true, true, 12, 16); acceleration.y = 100; offset.y = 4; offset.x = 2; height = 9; width = 8; addAnimation("walking", [1, 2, 3], 10); addAnimation("still", [0]); decisionCounter = 0; decisionGoal = 5; facing = true; } public override function update():void { super.update(); decisionCounter += FlxG.elapsed * 3; if (decisionCounter >= decisionGoal) { makeDecision(); decisionCounter = 0; } if (velocity.x > 0) { facing = true; play("walking"); } else if (velocity.x < 0) { facing = false; play("walking"); } else { play("still"); } } public function makeDecision():void { decision = Math.random(); if (decision<= .2) { velocity.x = 0; } else if (decision <= .6 && decision> .2) { velocity.x = -30; } else if (decision<= .6) { velocity.x = 30; } } public override function hitWall():Boolean { velocity.x *= -1; return true; } } } |
Line 4: You’ll notice that Player is extended from FlxSprite. This means our Player is similar to a normal Sprite, but it will have a lot more functionality like built-in animations, velocity, and it will self-update.
Line 6: We’re embedding an image class from the selected filepath, calling it the PlayerImage class. This image is a sprite sheet for our player. For Flixel, you’ll want to make sure your sprite sheets are organized as one horizontal row.
Line 14: Once again, we are calling super to pass some variables to the FlxSprite class . Here we are passing:
1. The image we embedded on line 6.
2. The X position being passed in.
3. The Y position being passed in.
4. “true” for whether or not it is animated .
5. “true” for whether or not we should flip the image depending on which way the sprite is facing.
6. The width of each displayed frame.
7. The height of each displayed frame.
Line 15: The positive y acceleration will act like gravity and make our player fall.
Lines 16-19: This is collision data. The offset is how many pixels from the upper left corner of our image should the collision box start. And the width and height are how many pixels of the image should be used for collision.
Lines 20-21: addAnimation is a FlxSprite function. All we do is give it:
1. A name in quotes so it is treated as a String.
2. An array that shows which frames of our sprite sheet should be used in the animation. Our “walking” animation uses frames 1, 2, and 3, and our “still” animation just uses frame 0.
3. At what speed should it animate(in frames per second)? We’ll leave this blank on our “still” animation since it doesn’t require multiple frames.
Lines 22-23: These variables are just to control how often the sprite decides to move.
Line 24: “facing” is a Boolean that FlxSprites have to indicate whether or not to flip the image.
Line 26: We’re overriding FlxSprite’s update function to add a little more customization for our Player. We’re still calling super.update(), because we’re not replacing FlxSprite’s update–we’re just adding to it.
Lines 29-34: Here we’re calling the makeDecision function every time our decisionCounter reaches the decisionGoal time. The “elapsed” variable in the FlxG class represents how many seconds have passed since the last frame(it usually returns a small fraction of a second).
Lines 35-48: We’re just telling our sprite what animations to play depending on the velocity.
Lines 50-64: The makeDecision function just rolls a random number and makes the sprite move left, move right, or stop.
Line 66: Here we override the hitWall function to make our Player go the opposite direction when hitting a wall.
Whew, now onto our last class, GameState.as:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | package com.game { import com.adamatomic.flixel.*; public class GameState extends FlxState { [Embed(source = "../../data/tiletest.png")] private var Tiles:Class; [Embed(source = "../../data/particlesheet.png")] private var ParticleImage:Class; [Embed(source = '../../data/map.txt', mimeType = "application/octet-stream")] private var Map:Class; public var player:Player; public var playerLayer:FlxLayer; public var mapLayer:FlxLayer; public var map:FlxTilemap; public var emitter:FlxEmitter; public var particleLayer:FlxLayer; public var explosionCounter:Number; public var explosionGoal:Number; public function GameState():void { super(); initMap(); initPlayer(); initParticles(); this.add(mapLayer); this.add(particleLayer); this.add(playerLayer); } override public function update():void { super.update(); map.collide(player); explosionCounter += FlxG.elapsed * 3; if (explosionCounter >= explosionGoal) { emitter.x = Math.random() * 120; emitter.y = Math.random() * 30; emitter.reset(); explosionCounter = 0; } } public function initPlayer():void { playerLayer = new FlxLayer(); player = new Player(20, 50); playerLayer.add(player); } public function initMap():void { mapLayer = new FlxLayer(); map = new FlxTilemap(new Map, Tiles, 1, 0); mapLayer.add(map); } public function initParticles():void { explosionCounter = 0; explosionGoal = 5; particleLayer = new FlxLayer(); emitter = new FlxEmitter(0, 0, 0, 0, null, -1.5, -100, 100, -100, 100, 0, 0, 200, 100, ParticleImage, 100, true, particleLayer); FlxG.state.add(emitter); } } } |
Line 4: Note that our GameState class is extended from FlxState. You may want to separate the play state and menu state into two different FlxStates. There’s no real limit to how many FlxStates you can switch between in your FlxGame.
Lines 6-8: Here we’re just embedding images used for our tiles and particle effect. Also we’re embedding a text file that will show our tilemap where each tile should go.
Lines 25-27: Adding all of the layers in their proper order. Here we’re first drawing the map, particles, then the player.
Line 32: This demonstrates Flixel’s built-in collision with the map. Pretty simple, eh?
Lines 34-41: We’re just exploding a particle effect in a random location every so often. No real point to this other than to show the particle system.
Lines 43-48: We make a new Player and a new FlxLayer and add the Player to the Layer. FlxLayers will just keep track of the drawing order for you.
Lines 49-53: New FlxTilemap with it’s very own FlxLayer. The FlxTilemap uses:
1. The map text file we defined on line 8.
2. A sprite sheet for the tiles that we defined on line 6.
3. What is the first tile that should be used for collision? We have 2 tiles, 0 and 1. We only want our player to collide with 1.
4. What is the first tile that should be drawn. We’re drawing both 0 and 1. 0 is our background.
Line 60: This is where we define our particle emitter. The FlxEmitter class takes in a ton of variables, thus allowing us to customize our particle effects fairly well:
1. X position of the emitter.
2. Y position of the emitter.
3. How wide the emitter should be.
4. How tall the emitter should be. The emitter fires particles from anywhere within it’s width and height.
5. “null” — this is an optional array of predefined sprites. We’re just going to use a sprite sheet instead.
6. This “-1.5″ is the lifespan of the particles. Negative numbers represent the lifespan of particles fired at one time. A positive number tells the emitter how often to fire off particles. How do you define the lifespan of particles that are not fired off all at once? I don’t believe Flixel has built-in capability to tweak that with its current version.
7-10. These are the minimum and maximum X and Y velocities.
11-12. Minimum and maximum angular velocity or rotation.
13. How much gravity should be applied? The default is 500.
14. This is the drag, which is a deceleration of the particles as they persist.
15. Here we can give it an image. We’re passing in the sprite sheet that was defined on line 7.
16. Quantity– how many particles should we use?
17. This variable tells whether or not we’re using a single image or a sprite sheet. “true” indicates that we are using a sprite sheet. It will automatically cut our sheet up into different particles as long as our frames are square.
Line 61: It is important that we add the emitter to the FlxG.state, or we will not see the particle effect.
If everything is correct, these classes should produce the program below: an animated sprite colliding with a tile map, complete with randomly placed particle explosions every few seconds. You’ll notice the default “Pause” screen is not correct, and I’ll cover how to customize the pause screen in another tutorial. If you have any questions, feel free to email me at theshadywizard[at]gmail[dot]com.

Nice tutorial. Really helped me. 2 little issues though:
The guy starts in the top left and gets stuck there.
There is a pure vertical row of purple tiles on the far left.
I’m also having trouble getting it to play from FlashDevelop. FD works with other projects, but not this one. To make it work I have to build it’s “release” form and then run the index file
Interesting, Do you know what version of Flixel you are using? There have been several recent updates that have massively changed the Flixel code. I believe this tutorial is written with v1.25 and the current version is 1.5X. I might go back through and update it for 1.5.
I was also wondering what sort of errors you received trying to run this with FlashDevelop.
Thanks for the feedback, it is much appreciated!
Thanks for the tutorial. Its simple and explains very well.