Talking about Platform game game, Actionscript 3, Flash and Game development.
During these days I am playing a bit with FlashPunk and I want to share with you a couple of examples.
We are going to build a simple platform game.
Getting the required software
While most developers use Flash Builder or FlashDevelop, I will use Flash Professional CS5.5, so the first thing you should do is getting a copy of it. You can get a fully functional 30 days trial at this page.
Then, download the latest release of FlashPunk from this page, and you are ready to go.
Preparing the worspace
All in all, FlashPunk is just an AS3 library, and although it has been developed for being used outside the Flash IDE, you just have to copy the net
foder into your project folder and you are ready to go.
Hello FlashPunk
At this time in your main class (I called mine punk
), enter this code:
package {
import net.flashpunk.Engine;
import net.flashpunk.FP;
public class punk extends Engine {
public function punk() {
super(640,480,60,false);
}
}
}
I said FlashPunk has been developed for being used outside the Flash IDE, and that’s it… we haven’t Sprites or Movieclips, but the class extends Engine
FlashPunk’s class.
This line
super(640,480,60,false);
Calls the constructor of the extended class, that is Engine
constructor, with these arguments:
width: the width of your game in pixels
height: the height of your game in pixels
frameRate: the game framerate, in frames per second (default: 60)
fixed: true if a fixed-framerate should be used, false (default) otherwise.
Test the movie and you will see a dark background color, no matter the Stage color.
Your FlashPunk project works!
Adding some walls
When it’s time to add graphics to our FlashPunk games, we have to draw them with our preferred paint software. Using Photoshop, I made a 32×32 pixels square and called saved it as wall.png
in a newly created assets
folder in the same level of net
(the one which contains FlashPunk library).
Then change punk.as
this way:
package {
import net.flashpunk.Engine;
import net.flashpunk.FP;
public class punk extends Engine {
public function punk() {
super(640,480,60,false);
}
override public function init():void {
FP.screen.color = 0x222233;
FP.world=new theWorld();
}
}
}
What happened? We added a new function called init
, overriding the init
method of Engine()
. This will allow us to initialize the game. FP.screen.color
lets us set the background color, specified as an hexadecimal value.
Then, we define world
, the main game container, with theWorld
class. This class will contain the game itself.
Let’s see the content of theWorld.as
:
package {
import net.flashpunk.World;
public class theWorld extends World {
public function theWorld() {
for (var i:int=0; i<20; i++) {
add(new theWall(i,0));
add(new theWall(i,14));
}
for (i=0; i<14; i++) {
add(new theWall(0,i));
add(new theWall(19,i));
}
for (i=1; i<5; i++) {
add(new theWall(5-i,14-i));
add(new theWall(8+i,5+i));
add(new theWall(2+i,10-i));
add(new theWall(13+i,8-i));
}
}
}
}
There isn't that much to say, we are just creating a lot of theWall
instances. So the interesting part comes with the creation of theWall.as
:
package {
import net.flashpunk.Entity;
import net.flashpunk.graphics.Image;
public class theWall extends Entity {
[Embed(source='assets/wall.png')]
private const WALL:Class;
public function theWall(posX:int,posY:int) {
graphic=new Image(WALL);
setHitbox(32,32);
type="wall";
x=posX*32;
y=posY*32;
}
}
}
As you can see, the class extends FlashPunk's Entity
class.
At lines 5 and 6 the wall picture is embedded into a class called WALL
.
Then the constructor wants the column and row position as arguments.
Line 8: Assigns the wall picture to theWall
entity. This way, at every theWall
instance, our wall.png
pucture will be added to stage.
Line 9: setHitbox
method defines the hit box around the entity, useful when we'll have to deal with collisions. It works in the same way as the hit box used for collision tests with AS3.
Line 10: type
property is useful to group entities. This way we'll only have to check for collision with wall
group rather than for each theWall
entity.
Lines 11-12: simply placing the entity in the world.
This is our game at this step:
Only a bunch of walls. Let's add the player.
Adding the player
Using Photoshop, I created a cyan 13x26 pixels box and saved as player.png
in assets
folder.
Just like I added the walls, I am adding the player in theWorld
class at line 5
package {
import net.flashpunk.World;
public class theWorld extends World {
public function theWorld() {
add(new thePlayer);
for (var i:int=0; i<20; i++) {
add(new theWall(i,0));
add(new theWall(i,14));
}
for (i=0; i<14; i++) {
add(new theWall(0,i));
add(new theWall(19,i));
}
for (i=1; i<5; i++) {
add(new theWall(5-i,14-i));
add(new theWall(8+i,5+i));
add(new theWall(2+i,10-i));
add(new theWall(13+i,8-i));
}
}
}
}
thePlayer
class will extend Entity
and it's the latest class we will add in this tutorial. It's a bit longer than the previous classes, but not that hard to understand:
package {
import net.flashpunk.Entity;
import net.flashpunk.graphics.Image;
import net.flashpunk.utils.Input;
import net.flashpunk.utils.Key;
import net.flashpunk.FP;
public class thePlayer extends Entity {
private var power:Number=0.2;
private var jumpPower:Number=10;
private var hFriction:Number=0.95;
private var vFriction:Number=0.99;
private var xSpeed:Number=0;
private var ySpeed:Number=0;
private var onTheGround:Boolean=false;
private var gravity:Number=0.3;
[Embed(source='assets/player.png')]
private const PLAYER:Class;
public function thePlayer() {
graphic=new Image(PLAYER);
setHitbox(13,26);
x=305;
y=225;
}
override public function update():void {
var pressed:Boolean=false;
if (Input.check(Key.LEFT)) {
xSpeed-=power;
pressed=true;
}
if (Input.check(Key.RIGHT)) {
xSpeed+=power;
pressed=true;
}
if (collide("wall",x,y+1)) {
onTheGround=true;
ySpeed=0;
if (Input.check(Key.UP)) {
ySpeed-=jumpPower;
}
} else {
ySpeed+=gravity;
}
if (Math.abs(xSpeed)<1&&! pressed) {
xSpeed=0;
}
xSpeed*=hFriction;
ySpeed*=vFriction;
adjustXPosition();
adjustYPosition();
}
private function adjustXPosition():void {
for (var i:int=0; i
First, let's have a look at the class level variables:
private var power:Number=0.2;
private var jumpPower:Number=10;
private var hFriction:Number=0.95;
private var vFriction:Number=0.99;
private var xSpeed:Number=0;
private var ySpeed:Number=0;
private var gravity:Number=0.3;
power is the thrust for the horizontal speed
jumpPower is the thrust for the jump
hFriction is the horizontal friction
vFriction is the vertical friction
xSpeed is the horizontal speed
ySpeed is the vertical speed
false
otherwise
gravity is the gravity force
Then, in the same way as the wall, player.png
image is embedded in a class called PLAYER
.
At lines 18-21 I define player's image, hit box and position in the same way I made with the walls.
The update
function I had to override manages player movement:
Line 24: a local variable called pressed
is created and takes a false
value. This variable will be true
if the player is pressing left or right arrow keys, false
otherwise.
Line 25: here is how FlashPunk checks for pressed keys, in this case left arrow key.
Line 26: adjusts horizontal speed
Line 27: we now know the player pressed the left (or right) arrow key
Lines 29-32: same thing when the player pressed the right arrow key
Line 33: this is how FlashPunk checks for collisions: collide
method wants three arguments: the entity or group of entities to check for the collision (wall
group in this case, that is any theWall
entity), and the x and y position where the entity is supposed to be placed.
In this specific case I am checking if the player, placed one pixel below its actual position, is colliding with the walls. That is, the player is on a platform.
If the player is on a platform, we set its vertical speed to zero (line 34) and check if the player is pressing up arrow key (line 35). In this case, the vertical speed is updated by subtracting jumpPower
. This is how the player jumps!
If the player is not on a platform (line 38), the vertical speed is updated by adding the gravity.
Lines 41-43: stop player movement if it's too slow and the player is not pressing left or right arrow keys.
Lines 44-45: apply friction to player's speed.
Lines 46-47: adjust player x and y position according to its speed and the environment. This is made with adjustXPosition
and adjustYPosition
functions which work in the same way, moving the player in the current direction pixel by pixel until the movement is completed or the player hits a wall.
Let's see how does adjustXPosition
work:
Line 50: loop from zero to the absolute value of horizontal speed
Line 51: checks for collision with a wall one pixel on the left or on the right of the player, according to its horizontal speed. sign
method returns 1
is its argument is positive, -1
if it's negative and 0
if it's zero.
Line 52: if there's no collision, increases/decreases player x position according to its horizontal speed.
Lines 54-55: if there is a collision, set the horizontal speed to zero and exit the loop.
adjustYPosition
works in the same way.
This is the final result:
Use left/right arrow keys to move, up to jump.
Download the source code, with FlashPunk library, and all the graphic assets.
Is there any other feature you would like to see?
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.