I’ve been developing a totally new game for Tetrageddon. It’s going to be available for mobile (iOS, and Android), as well as the desktop.
This is an HTML5 game (for a change), with CreateJS, using FlashCC’s HTML5 Canvas document. Doing so will make things easier for me animation wise, as well as managing complex animated “cut scenes”, and other graphical aspects…
The game is codenamed “Face The Music” because it will essentially be about death and “giving up” — in a playful yet poetic pixel art style. :)
Best of all, “Face The Music” is a platformer game!
I will be documenting the development process, and releasing it as a series of tutorials that will walk you through creating this game. I will be doing this for all of Tetrageddon’s projects from now on, because I want to place even more emphasis on the “learning resource” aspect of Tetrageddon Games. This will provide excellent content for that.
The Basic Platformer
The finished product will behave like this. Sorry, it’s in the “programmer art” stage. :)
LEFT/RIGHT = Move
DOWN = Duck
UP = Jump (hold up to jump higher)
Falling off = Death
Getting to right of screen = Win (it’s a short game at the moment)
For starters head down to https://github.com/madrobby/keymaster and grab a copy of
keymaster.js. I’m using this because I figure I’ll want more complex keyboard functionality (maybe I’ll change this later, but for now I’m using this).
The code to import this will be as follows (first thing, first frame):
There are some miscellaneous functions that will handle returning various calculations.
num_randrange, which returns a random number between a minimum and maximum specified value…
gotoAndStopRandom, which sets a sprite to a random frame (I’ll be using this for the player sprite in later versions of the game).
Moving on to the actual meat of the game, we’ll set up the “world properties” (like gravity, friction, and stage width/height, and other necessary Arrays, variables…)
Most of this is fairly self explanatory.
bool_lastpanel is the current screen you’re on. I’m dividing the game up like it’s comic book panels that you are playing through. This being set to true indicates that once you leave the right of the screen, you “win”.
The last two arrays:
arr_colidable, are sprites that will check against each-others collision… I mean, I put everything in their respective arrays to handle the “object type”, if it’s in
arr_colidable then it’s a platform and the player (
arr_players) will stand on it.
I’m wrapping up managing sprites into a set of functions. The first one (
addSprite) is going to be responsible for adding sprites. It takes five properties. They are as follows.
libItem = name of library item. As you can see, I have any sprites that need to be manipulated through code added on the “first frame”. This way it registers — workaround for not having library linkages.
name = new name of the added sprite.
arr = the array it should be added to. Such as
arr_players (for a player),
arr_colidable (if it’s a collideable platform).
x = x position.
y = y position.
addSprite creates a clip via
var clip = new libItem();
Adds it to
_stage (our “root timeline” as saved in the variable from the above setup), names it, and adds it to the specified array, then places it at the desired x/y coordinates.
removeAllSprites(). This one gets called for game win, or game over (dying). To clear off everything on the stage. It simply loops through all the arrays, and removes their contents from
And finally we have a set of functions specific to managing the player’s states;
player_win are basically identical, but they set the
_stage to a different “frame”.
player_die first calls
evnt_removeAll(), which removes all event listeners (will explain later). Then
removeAllSprites, then sends
_stage to “gameover”.
player_win does the same thing.
player_duck handles the player’s “crouched” state. The player ducks when you press the
DOWN key, or he will be ducked down (in an “ouch my head!” animated state) if a collision takes place where the player hits his head on the bottom of a platform… like, jumps up against something… as a cute detail.
To duck, the players ducking state is set to
true, and then the player’s height reduced (I will explain player properties later). If a certain type
"ouch", then set the player to that state…
The finished function is as follows:
Finally, we’ll add the sprites to the stage.
This is a prototype of a game “level”… a very, very, small level. So we’ll create a few platforms (of different types), and the player.
Starting with the player.
The player is first added, and the currently controllable player saved to a variable (
mc_frombie), so that any collision detection, and controlling will only apply to him — in the event that I want to add more controllable characters, I can just pull from the array and re-assign
mc_frombie to the desired controllable sprite.
Then we have the player properties (values), which are set manually.
We set the
.height, this is important for collision detection (which uses width height to check). When the player crouches/ducks the
.height is set to the crouch value. These values will change throughout the game, depending on the player’s state.
Then there are the last remaining properties that have to do with the physics, and states like jumping, if the player is on the ground, and ducking…
mc_frombie.speed = the speed of the player.
mc_frombie.jumpHeight = how high the player’s initial jump is. The player jumps higher if the up key is held down longer. If the up key is tapped then the player jumps at this default value.
mc_frombie.velX = the x velocity.
mc_frombie.velY = the y velocity.
mc_frombie.jumping = is the player jumping?
mc_frombie.grounded = is the player on the ground (on a platform)?
mc_frombie.ducking = is the player ducking (crouching)?
In conclusion, player setup looks like this:
Now we set up our platforms/floors. There are two types of floors. One is the classic version where if you hit the sides, and bottom, it will register as a collision and the player may not move there. The second is the one where you can jump through it, and land on it… Hope that makes sense. Envision the first being a box, and the second is like a cloud…
Each platform is added to
arr_colidable, and variable assigned to it.
Each platform needs to have its own
width/height set, and then its
isPlatform boolean set.
False means you can’t jump through it (collision registers on all sides),
true means you can jump through it and land on it (collision only registers for top).
We have four platforms to start with.
The end result looks like this:
I wanted the simplest, most basic, and corner cutting approach possible, because I want to move on to making the game. I never really thought about the finer aspects of collision detection before, since there are so many libraries available. You can just use what’s already provided. It was interesting to wrap my head around it.
I found Somethinghitme’s explanation of collision detection to be an excellent example for getting my head thinking in those terms. I recommend checking it out, it’s basically what I’m doing here…
To begin we will calculate the amount of overlap between the two objects (object1 and object2), on both sides, top and bottom:
And then the half width and height of both objects. This will be used later for determining which side the collision occurred on.
Then we’ll move on to our
if block. First to just get a collision (regardless of what side):
In this block we’ll fine tune our check, and return what side the collision took place on.
First we’ll set up the string
direction_string. This will return
Then we have our distance variables (as the comment suggests) between the two objects:
The last set of variables is where the magic happens! This
oY determine what side the collision occurred on. Simply put:
Moving on to our final set of
if‘s… These check on what side/top/bottom the collision took place, and set
direction_string to that side. Then
object1‘s (the player)
.x is set to
oX (landed on it, or can’t go beyond it)… just force it to that value.
All that looks like this:
Finally return the value of
direction_string. We worked hard to get this!
colisionCheck is as follows:
To use the above, we just need to loop through our arrays, and check if
mc_frombie collided with any
Basically it will look like this:
We will handle this in a Ticker, later.
Physics & Player Movement
I created a couple of physics prototypes for this. They are both good examples of basic “physics”, and are great for getting your head into it.
Click to generate particles on mouse position.
DOWNLOAD SOURCE HERE
Click FIRE! to generate particles.
DOWNLOAD SOURCE HERE
In this game’s case, the approach is similar, except we are also checking for collision, and then we handle that appropriately (depending on platform type). Since we already have collision detection done, we just need things to fall on things now…
We’ll start with setting up the Ticker (to update positions), and the keyboard (to move the player).
Like I said, I’m using
keymaster.js for controlling… as things later turned out, I needed to use
KEY UP events (releasing
UP after holding it down – to jump really high, and “un-crouching”), so I had to resort to old-school keyboard functionality. This is messy, and not efficient (I know!). I will be phasing out
keymaster.js later (or fixing it so I use only
keymaster.js), but (for now) we have two approaches…
We’ll create the events:
And also make sure to create
evnt_removeAll(); (usage explained above). I realize that you could also use
removeAllEventListeners([type]) to remove absolutely everything, but I’m not sure what events I will want to keep in the future, so I’m doing this for now…
Now we’ll set up the
keyCode‘s necessary for
There are two classic key down and key up functions. These take care of ducking, and jumping.
Key down manages jumping mostly (at the moment). This increases
mc_frombie.jumpHeight. The longer up is pressed the higher the player will jump. This is going to be an important mechanic later on in the game. It also sets
true to indicate that a key is being pressed.
Key down looks like this:
Then there’s the key up event. It sets
false, indicating that the key has been released.
In the case of the up key having been released (if the player isn’t already jumping), it sets
true. The jump will now be handled in the
Ducking is a little simpler. If the
S key are released, and
mc_frombie is ducking, set ducking to
false. The actual “un-ducking” will also be handled in the
KEY UP event is as follows:
Moving on to the actual player physics, I’ll break down the basics of how it works…
Jumping is the first thing you’ll notice. As the
if condition suggests, you may only jump if
true (this is set in KEY UP event),
mc_frombie isn’t already jumping, and
mc_frombie is on the ground.
If this is the case then jumping is set to
true, grounded is
false (he’s jumping now), and ducking is
false (resets ducking if he was ducking), and then set the
velY to move:
That’s the important part.
The last two
bool_keyDown being set to
false basically resets things. Once player is back on the ground you can jump again.
The above looks like this:
There’s another condition that follows which resets
mc_frombie.jumpHeight to the default value.
After jumping you’ll notice ducking. Ducking is simple. If
S, and you’re not jumping, and on the ground,
player_duck("duck"); is called.
You may then unduck only if
height is less than the default (so no conflict with other
gotoAndStop labels takes place), and if
false. If that’s the case then the
height is set back to normal, and player is set back to
Unduck looks like this:
Finally we have our left and right movements.
Left/right looks like this, and is fairly self explanatory:
After we’re done with all the above, we need to set mc_frombie’s
velY (friction, and gravity), and set
false. Basically calculate all the above to apply later… which looks like this:
Then we have the fun part! Checking collision, and acting appropriately.
We loop through
arr_colidable, and set variable
dir to the returned value of
Then there’s our condition for each direction (left, right, top, or bottom).
Left and right are basically the same thing. They stop
velX, and set
Bottom means you’re standing on the ground. So
mc_frombie.grounded is set to
mc_frombie.jumping is set to
false (you’re not in the air anymore).
Top means that he hit his head on the bottom of a platform.
velY is set back (push him down), and then the
"ouch" state is set — he’s ducking, and I’ll have a cute animation there.
The entire block looks like this:
After that we manage
velY if he’s on the ground (not jumping anymore, above collision with ground took place).
velY to 0 (default state):
FINALLY, we need to set the player’s
y to the calculated values.
The last bit manages the player falling off the screen and dying, or walking off the right and winning:
That’s it! The entire thing looks like this:
Finished! Now we have the groundwork for a simple platformer game.
This is stage one. Obviously it’s a work in progress, and I still need to optimize parts, but… small steps! :)
I’m now moving on to incorporating a few levels, and some of the features I want in the game… as well as WAY better artwork. :)
Or check out my other tutorials:
* Tutorial: Building A Game In Edge Animate (Offender)
* Tutorial: Building A Game With Flash HTML5 Canvas & CreateJS (Haxatron 2000)