An Introduction to FlashPunk: The Basics

Learn the basics of how FlashPunk works - an amazing library to save you time and help you create the perfect game!


Final Result Preview

Let's take a look at the final result we will be working towards:

Use the arrow keys to move your character (the blue guy). The red/brown guy is an NPC; the shaded red area is a danger zone, and the green box is a button. You'll learn how to create all this in this tutorial.


Step 1: What Is FlashPunk?

FlashPunk logo

FlashPunk is an ActionScript 3 library created for the development of Flash games. Basically, it does all the hard work for you and lets you focus entirely on developing your game, rather than on the engine behind it. The best part about it is that you don't need Flash Pro to work with it: you can do everything with a free code editor like FlashDevelop. Not to mention it's way faster when it comes to drawing things on screen, since it uses blitting!

This tutorial will go through all the basics of FlashPunk. After following it, you'll be ready to make a simple game with this amazing library!


Step 2: Initializing the Engine

Begin by downloading the latest version of FlashPunk from the official site (this tutorial uses the version from August 30, 2011). Put the "net" folder, with all its contents, in your "src" folder.

FlashPunk has a class called Engine. This class is what starts everything in the library. Think of it as a Main class, but with special code to power up all the classes in FlashPunk. In order to use the Engine class, we will modify the Main class a little bit.

Now, our class extends Engine. In Main's constructor, we need to make a call to the Engine constructor: this is what sets the important information about the game: width, height, framerate and whether the engine should run at a fixed framerate or not.

There is a function that can (and must be) overridden from the Engine class: the init() function. It will run only once, and will initialize everything to get the game working.

I'm pretty sure everyone wants to put something on the screen and see this engine working! Because of that, the next few steps will cover the very basics of the elements of FlashPunk, adding depth as the tutorial goes on.


Step 3: Worlds and Entities

In FlashPunk, there are elements called Worlds and Entities. These are the main elements of the library, and you'll work with them from the beginning to the very end of your game.

Worlds are pretty much like what is commonly known as a "screen". Everything in your game will happen in a world: the main menu is a world that will give you access to the actual game world, where you will fight some enemies and die, which will lead you to the game over world, with your scores and statistics about how well you did. More about worlds will be explained later.

Entities are exactly what they seem to be; they live in a world and do something in it: a button is an entity; your character is an entity; enemies and bullets are entities. They are the things that give life to the game.

Given that, we will create the game world (there's time to make the main menu world later, let's jump to some action!) by extending FlashPunk's World class:

Now that you have created a world, you need to tell FlashPunk that you want this world to be the active one. Let's do it in Main.as:

And don't forget to import net.flashpunk.FP!


Step 4: Adding an Entity, and Giving It an Image

Now that we have our world, we can make an entity by extending the Entity class and adding it to our game world:

And in GameWorld.as:

Notice that if you compile and run the game, the entity doesn't appear in the screen. That's because it has no image yet! Every entity can have a graphic object. This graphic can be a single image, a spritesheet with animations, tiled images -- pretty much anything.

We will add this little image to our entity:

Our Entity

An entity's graphic can be accessed by the graphic property. That's how we are going to put the image in it! First, embed it; then, just pass it to Image's constructor and FlashPunk will take care of transforming that into something visible for you. Compile and run now. Surprise! Our entity is there!

This is what you should get:

The entity on the screen

Step 5: Making the Entity Move

Now that we have our entity on the screen, what about making it move? Each Entity has a function called update(), which you must override to use. This function is called by every world in the beginning of each frame. If you need to make your entity move, that's the place where you put your code!

And don't forget to import:

See it in action! (Refresh the page if you can't see anything here.)

You may have noticed the use of FP.elapsed. FP.elapsed gives the amount of time that elapsed since the last frame (in seconds), making it very easy to create time-based motion. However, for that to work, you must have set the fourth parameter to the Engine's constructor to false. Remember that (Step 2)? Setting it to false means that you want FlashPunk to run with a variable timestep, whereas setting it to true makes FlashPunk run on a fixed timestep. Doing the latter, you don't need to use FP.elapsed. You will know that every time the update() function is called, a frame has passed.


Step 6: Move the Entity as You Wish With Keyboard Input

We've got the entity moving on just one direction in the last step. Introducing keyboard input: now you will be able to move the entity to where you want!

FlashPunk has a class called Input which takes care of both keyboard and mouse input. In this tutorial, we will only use keyboard input for movement. It is very easy:

And the import statements:

Input.check() returns true if the Key passed as an argument is being pressed at the time the function has been called. There are other very useful functions, like Input.pressed(), which returns true if the key has been pressed at the time the function has been called (i.e. the key was up a frame ago and is now down), or Input.released(), which does exactly the opposite.

Another interesting thing that the Input class allows us to do is to define many keys under a single name. For example, we could define Key.UP, Key.W and Key.I as "UP", and only check for Input.check("UP"). That way, we can improve our function:

And this is what you should get:


Step 7: More About Entities

Entities can do a lot more than just move around and have images. Let's take a look at what surprises they can hold!

Entities have a property called type. You can set this property to any string you want. This allows you to organize your entities into groups, which will prove very useful in the next step (about worlds). We can, for example, set our entity's type to "GameEntity":

Following on that, we have the useful world property and the added() and removed() functions. The world property allows you to access the world from within the entity's code once the entity has been added to an world. It is like the stage property in common Flash development; the functions are like the ADDED_TO_STAGE and REMOVED_FROM_STAGE event listeners. Here's an example of the functions working in GameEntity.as:


Step 8: Deeper Look at Worlds

It is time to take a deeper look at worlds and how they work. First of all, FlashPunk can only have one world running at once, but your game can have as many worlds as you wish, as long as only one remains active every time.

Worlds have update() functions just as entities do, but their function is a little different: there is actual code in the World class. That means you'll have to call super.update() every time you override this function.

Apart from entities, worlds can also have graphics added to them. Graphics are images that don't need to be updated by you (FlashPunk still creates an entity to add them to the world, so the engine will still send a call to an update() function). You can add them by calling addGraphic().

The most important thing about worlds is that they have several functions to retrieve certain entities: getType(), getClass(), getAll(), getLayer() and getInstance(). That way, you can have the world return an array of all the bullets currently in the game, so that you can perform a check against all of them for collision. Very handy, I must say!

Take a look at the code added to World.as. We will use a second image as well:

Our second entity

And don't forget to import net.flashpunk.graphics.Image!

In this code, the addGraphic() function call adds another graphic similar to _gameEntity's graphic - think of it as a NPC! - to the world in the position (50, 50). Lines 23-31 show an example of retrieving only entities of a particular kind: we call getType() to get only entities of the "GameEntity" type (currently only one entity). After that, we iterate through every entity retrieved and prevent them from getting past the right and bottom borders. (So, the entity can move outside the screen, but not far.) Simple, isn't it?


Step 9: Animations

Time for something more interesting! FlashPunk supports animations of all kinds. All you have to do is, instead of creating an instance of Image, create an instance of Spritemap. This class receives a spritesheet and allows you to map frames and link to animations.

In our entity's class, embed this spritemap:

Our Entity's Sheet

Then, create an instance of Spritemap and pass the spritesheet as a parameter to the constructor. After that, it's all about calling the add() and play() functions!

The constructor of Spritemap (line 19) takes four arguments: a source to get a graphic from, the width and height of each frame of the spritesheet and a callback function to call when the animation ends (optional). In GameEntity's constructor, we create the Spritemap and define two animations: "Stopped", which only contains the first frame and runs at 0 fps (stopped!) and "Blinking", which contains all frames and runs at 24 frames per second.

The rest of the code is there to play the "Blinking" animation every three seconds.

Take a look at our entity blinking:


Step 10: Collision

With everything running well, it's time to introduce another feature: collision detection. FlashPunk has a great collision detection system: all we need to do is set hitboxes for our entities and ask the world to check for collisions. For that, we will create another entity called Box which will contain the following graphic:

Box image

And inside GameWorld.as:

The setHitbox() function sets a rectangle that will act as a hit box for the entity. The first two parameters are the width and height of the box. The next two parameters (optional) are the origin coordinates (x and y) of the rectangle. Doing the same for GameEntity:

Now that we have both our entity and the box set up with hitboxes, we need to check for collisions in the world class:

The collideWith() function checks collision with the entity passed as an argument, virtually placing the first entity (in this case, _gameEntity) in the position specified by the second and third arguments.

Once a collision is detected, there must be a response to it. We will only change the position of the moving entity:

Take a look at the example. Try to move the entity into the box.


Step 11: Creating a Simple Button - Adding an Image

FlashPunk doesn't have any buttons by default. Almost all games need buttons, so in this step we will create a Button class. First of all, a button has three states (as you may know from common Flash development): "Up", "Over" and "Down". This spritesheet illustrates that:

A Button

And now let's start the class:

The setSpritemap() function sets a spritemap for the button and sets "animations" for the button. Always the image must have first the "Up" frame, then the "Over", followed by the "Down" frame. There's also a call to setHitbox(). The hitbox will be used to check whether the mouse is or isn't over the button's box.


Step 12: Creating a Simple Button: Up/Over/Down Controls, Callback

Now that we have our Button successfully showing an image, it's time to create up, over and down controls. We will do it by creating two Boolean attributes: "over" and "clicked". We will also detect whether the mouse is over the button's hit box or not. Add these functions in Button.as:

And don't forget to import net.flashpunk.utils.Input.

Following the logic in update(): first of all, both attributes (_clicked and _over) are set to false. After that, we check if the mouse is over the button. If it isn't, the attributes will remain false and the button will be in the "Up" state. If the mouse is over, we check whether the mouse button is currently down. If that's true, the button is in the "Down" state and _clicked is set to true; if it's false, then the button is in the "Over" state and the _over attribute is set to true. These attributes will define which frame the spritemap should go to.

This button will be useless if you can't detect when the user has effectively clicked it. Let's change the class a bit in order to support callback functions:

Our button is done! This code will allow you to pass a callback function (and optionally an argument) to your button, so whenever the user clicks the button, the function will be called.


Step 13: Creating a Simple Button: Adding It to the Screen

Many steps and nothing on the screen... Time to put a button in there! It's as simple as adding this code in GameWorld.as:

Now all you have to do is compile the project and the button will be there!


Step 14: The Console

And now the final feature from FlashPunk that will be presented in this tutorial! The Console is FlashPunk's tool for debugging: it features logs, which are pretty much like traces; shows the time taken to run important engine step; and displays how many entities are on screen and the current FPS. It's a great tool to use when developing your game. To enable it, just add the following line to Main.as:

And to log anything in it, use the FP.log() function. For example, let's change that trace() call:

That's pretty much it! You'll see that the "Output" part from the debugging console now shows the log. You can go ahead and change all the trace() calls in our code to calls to FP.log().


Conclusion

And that's our introduction to FlashPunk, covering the most important aspects of this amazing library: entities, worlds, images and animations; collision, buttons, input and movement. I hope you'll like this library as much as I do - it really makes work easier!

Tags:

Comments

Related Articles