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.
Let’s begin!
*************
The Basic Platformer
The finished product will behave like this. Sorry, it’s in the “programmer art” stage. :)
[iframe src=”http://nathalielawhead.com/sourcefiles/Tutorial_HTML5_Platformer_Part1/FaceTheMusic_Tutorial1.html” width=”800″ height=”480″]
http://nathalielawhead.com/sourcefiles/Tutorial_HTML5_Platformer_Part1/FaceTheMusic_Tutorial1.html
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)
*************
The Setup
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):
//import .js var js_keys = document.createElement("script"); js_keys.src = "libs/keymaster.js"; js_keys.type = "text/javascript"; document.getElementsByTagName("head")[0].appendChild(js_keys);
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…
//Math function num_randrange(num_max, num_min) { return Math.ceil(Math.random()*(num_max-num_min)+num_min); }
and gotoAndStopRandom
, which sets a sprite to a random frame (I’ll be using this for the player sprite in later versions of the game).
//Timelines function gotoAndStopRandom(clip){ clip.gotoAndStop(Math.ceil(Math.random()*clip.timeline.duration)); };
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…)
this.stop(); //Stage _stage = this; num_stageWidth = 800; num_stageHeight = 480; //"World" properties friction = 0.6; gravity = 0.8; //Booleans bool_keyDown = false;//key is held down bool_jumpDown = false;//jump key is down bool_lastpanel = true;//false;//is this the last panel, if so the game will win after you leave the screen //Sprites //Every sprite set is stored in that set's own array - //for collision and sprite specific properties/functionality //the player mc_frombie = null; arr_players = [];//array of any hero sprites [0] = mc_frombie //ground arr_colidable = [];//array of any colidable platform
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_players
and 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.
*************
Managing Sprites
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.
//create the sprite //usage: addSprite(lib.Player, "mc_frombie", arr_players, 150, 150); function addSprite(libItem, name, arr, x, y){ // var clip = new libItem();//lib.LINKAGE _stage.addChild(clip); clip.name = name; arr.push(clip); // clip.x = x; clip.y = y; };
Then there’s 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 _stage
.
//remove anything created by game //could use removeAllChildren, but I don't know what I might want to keep... function removeAllSprites(){ //get rid of the player for(var plr = 0; plr<arr_players.length; ++plr){ _stage.removeChild(arr_players[plr]); }; //get rid of anything colidable for(var col = 0; col<arr_colidable.length; ++col){ _stage.removeChild(arr_colidable[col]); }; };
And finally we have a set of functions specific to managing the player’s states; player_die
, player_win
, and player_duck
.
player_die
and 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 function player_die(){ //remove all listeners evnt_removeAll(); //remove all created children removeAllSprites(); // console.log("gameover"); //go to gameover _stage.gotoAndStop("gameover"); }; function player_win(){ //remove all listeners evnt_removeAll(); //remove all created children removeAllSprites(); // console.log("gamewin"); //go to gameover _stage.gotoAndStop("win"); };
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 "duck"
, or "ouch"
, then set the player to that state…
The finished function is as follows:
//ducking acts as an "ouch my head", and "be careful my head" animation //like he's sensitive about his head... aside from reducing his height so he can crawl through small areas function player_duck(type){ mc_frombie.ducking = true; mc_frombie.height = 10; if(type=="duck"){ mc_frombie.gotoAndStop("duck"); } //hit his head on something, now sees stars or some type of injury if(type=="ouch"){ mc_frombie.gotoAndStop("ouch"); }; };
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 .width
and .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:
//PLAYER addSprite(lib.Player, "mc_frombie", arr_players, 150, 150); mc_frombie = arr_players[0]; //player properties //width and height is set manually //this is the standing position //crouching is adjusted in the down arrow event (reduce height, and go to another frame) //this way I don't need fancy collision detection because I always know the w/h values... mc_frombie.width = 40;//66 mc_frombie.height = 110; // mc_frombie.speed = 6;//9; mc_frombie.jumpHeight = 1.5;//2 mc_frombie.velX = 0; mc_frombie.velY = 0; mc_frombie.jumping = false; mc_frombie.grounded = false; mc_frombie.ducking = false; // mc_frombie.stop(); gotoAndStopRandom(mc_frombie.mc_frombie);
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:
//GROUND addSprite(lib.Colidable_Floor, "mc_floor1", arr_colidable, 50, 300); mc_floor1 = arr_colidable[0]; //properties mc_floor1.width = 800; mc_floor1.height = 50; mc_floor1.isPlatform = false; //GROUND 2 addSprite(lib.Colidable_Floor, "mc_floor2", arr_colidable, 1000, 130); mc_floor2 = arr_colidable[1]; //properties mc_floor2.width = 800; mc_floor2.height = 50; mc_floor2.isPlatform = false; //GROUND 3 addSprite(lib.Colidable_Platform, "mc_floor3", arr_colidable, 300, 50); mc_floor3 = arr_colidable[2]; //properties mc_floor3.width = 100; mc_floor3.height = 50; mc_floor3.isPlatform = false; //Platform, you can walk through it, and jump up through it, but you can stand on it addSprite(lib.Colidable_Platform, "mc_platform1", arr_colidable, 500, 200); mc_platform1 = arr_colidable[3]; //properties mc_platform1.width = 100; mc_platform1.height = 50; mc_platform1.isPlatform = true;//if it is a platform you can stand on it, but hitting the bottom and sides does nothing
*************
Collision Detection!
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:
leftDist = (object2.x - object2.width/2) - (object1.x + object1.width/2); rightDist = (object1.x - object1.width/2) - (object2.x + object2.width/2); topDist = (object2.y - object2.height/2) - (object1.y + object1.height/2); bottomDist = (object1.y - object1.height/2) - (object2.y + object2.height/2);
And then the half width and height of both objects. This will be used later for determining which side the collision occurred on.
var hWidths = (object1.width / 2) + (object2.width / 2); var hHeights = (object1.height / 2) + (object2.height / 2);
Then we’ll move on to our if
block. First to just get a collision (regardless of what side):
if(leftDist < 0 && rightDist < 0 && topDist < 0 && bottomDist < 0){
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 "left"
, "right"
, "top"
, or "bottom"
.
Then we have our distance variables (as the comment suggests) between the two objects:
var xDist = object1.x - object2.x; var yDist = object1.y - object2.y;
The last set of variables is where the magic happens! This oX
and oY
determine what side the collision occurred on. Simply put:
var oX = hWidths - Math.abs(xDist); var oY = hHeights - Math.abs(yDist);
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) .y
or .x
is set to oY
or oX
(landed on it, or can’t go beyond it)… just force it to that value.
All that looks like this:
if (oX >= oY) { if (yDist > 0 && !object2.isPlatform) {//hit the top direction_string = "top"; object1.y += oY; } if (yDist < 0){//standing on it direction_string = "bottom"; object1.y -= oY; } } else { if (xDist > 0 && !object2.isPlatform) {//left of direction_string = "left"; object1.x += oX; } if (xDist < 0 && !object2.isPlatform) {//right of direction_string = "right"; object1.x -= oX; } }
Finally return the value of direction_string
. We worked hard to get this!
return direction_string;
The entire colisionCheck
is as follows:
//colision detection for player and platform (ground) function colisionCheck(object1, object2) { //amount of overlap leftDist = (object2.x - object2.width/2) - (object1.x + object1.width/2); rightDist = (object1.x - object1.width/2) - (object2.x + object2.width/2); topDist = (object2.y - object2.height/2) - (object1.y + object1.height/2); bottomDist = (object1.y - object1.height/2) - (object2.y + object2.height/2); //half widths and half heights of the objects var hWidths = (object1.width / 2) + (object2.width / 2); var hHeights = (object1.height / 2) + (object2.height / 2); // if(leftDist < 0 && rightDist < 0 && topDist < 0 && bottomDist < 0){ //left, right, top, bottom var direction_string; //distance variables var xDist = object1.x - object2.x; var yDist = object1.y - object2.y; //which side does the colision occur (get the side it occurs on) var oX = hWidths - Math.abs(xDist); var oY = hHeights - Math.abs(yDist); // if (oX >= oY) { if (yDist > 0 && !object2.isPlatform) {//hit the top direction_string = "top"; object1.y += oY; } if (yDist < 0){//standing on it direction_string = "bottom"; object1.y -= oY; } } else { if (xDist > 0 && !object2.isPlatform) {//left of direction_string = "left"; object1.x += oX; } if (xDist < 0 && !object2.isPlatform) {//right of direction_string = "right"; object1.x -= oX; } } //console.log("direction_string: "+direction_string); return direction_string; } }
To use the above, we just need to loop through our arrays, and check if mc_frombie
collided with any arr_colidable
.
Basically it will look like this:
for (var i = 0; i < arr_colidable.length; i++) { dir = colisionCheck(mc_frombie, arr_colidable[i]); console.log(dir); };
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.
[iframe src=”http://nathalielawhead.com/sourcefiles/Super_Simple_Snippets/gravity_gibsJS.html” width=”480″ height=”500″]
http://nathalielawhead.com/sourcefiles/Super_Simple_Snippets/gravity_gibsJS.html
DOWNLOAD SOURCE HERE
Click FIRE! to generate particles.
[iframe src=”http://nathalielawhead.com/sourcefiles/Projectiles/gravity_projectileJS.html” width=”480″ height=”500″]
http://nathalielawhead.com/sourcefiles/Projectiles/gravity_projectileJS.html
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:
//Events createjs.Ticker.addEventListener("tick", event_movement_ticker); document.onkeydown = evnt_KEYDOWN; document.onkeyup = event_KEYUP;
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…
//remove events function evnt_removeAll(){ createjs.Ticker.removeEventListener("tick", event_movement_ticker); document.onkeydown = null; document.onkeyup = null; };
Now we’ll set up the keyCode
‘s necessary for KEY UP
:
KEY_UP = 38; KEY_DOWN = 40; KEY_S = 83;
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 bool_keyDown
to true
to indicate that a key is being pressed.
Key down looks like this:
function evnt_KEYDOWN(event){ // if(!event){ var event = window.event; } //get ready for jump height - the longer it's pressed the heigher he will jump if (key.isPressed("up") || key.isPressed("w")) { mc_frombie.jumpHeight += .5; bool_keyDown = true; }; };
Then there’s the key up event. It sets bool_keyDown
to 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 bool_jumpDown
to true
. The jump will now be handled in the Ticker
event.
Ducking is a little simpler. If the DOWN
or S
key are released, and mc_frombie
is ducking, set ducking to false
. The actual “un-ducking” will also be handled in the Ticker
.
The finished KEY UP
event is as follows:
function event_KEYUP(event){ // if(!event){ var event = window.event; } // bool_keyDown = false; //now trigger the jump (only if not already jumping and the key is not down) //greater than default is how it tells if you triggered a jump) if ((!bool_keyDown && !mc_frombie.jumping) && (event.keyCode == KEY_UP)) { bool_jumpDown = true; }; //unduck - ducking is in ticker because it needs to happen imediately - there is a keydown delay in multiple key if ((event.keyCode == KEY_DOWN || event.keyCode == KEY_S) && (mc_frombie.ducking)) { mc_frombie.ducking = false; }; };
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 bool_jumpDown
is 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:
mc_frombie.velY = -mc_frombie.speed * mc_frombie.jumpHeight;
That’s the important part.
The last two bool_jumpDown
and 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:
if (bool_jumpDown && !mc_frombie.jumping && mc_frombie.grounded) { // mc_frombie.jumping = true; mc_frombie.grounded = false; mc_frombie.ducking = false;//reset ducking also if up is pressed // mc_frombie.velY = -mc_frombie.speed * mc_frombie.jumpHeight; //reset bool_jumpDown = false; bool_keyDown = false; }
There’s another condition that follows which resets mc_frombie.jumpHeight
to the default value.
if(!bool_jumpDown && mc_frombie.jumping && !mc_frombie.grounded){ mc_frombie.jumpHeight = 1.5; };
After jumping you’ll notice ducking. Ducking is simple. If DOWN
or S
, and you’re not jumping, and on the ground, player_duck("duck");
is called.
if ((key.isPressed("down") || key.isPressed("s")) && (!mc_frombie.jumping && mc_frombie.grounded)) { player_duck("duck"); }
You may then unduck only if height
is less than the default (so no conflict with other gotoAndStop
labels takes place), and if mc_frombie.ducking
is false
. If that’s the case then the height
is set back to normal, and player is set back to "walk"
.
Unduck looks like this:
if(!mc_frombie.ducking && mc_frombie.height<110){ mc_frombie.height = 110; mc_frombie.gotoAndStop("walk"); };
Finally we have our left and right movements.
Left/right looks like this, and is fairly self explanatory:
//left/right movement if ((key.isPressed("left") || key.isPressed("a"))) { if (mc_frombie.velX > -mc_frombie.speed) { mc_frombie.velX-=mc_frombie.speed; } } if ((key.isPressed("right") || key.isPressed("d"))) { if (mc_frombie.velX < mc_frombie.speed) { mc_frombie.velX+=mc_frombie.speed; } }
After we’re done with all the above, we need to set mc_frombie’s velX
and velY
(friction, and gravity), and set mc_frombie.grounded
to false
. Basically calculate all the above to apply later… which looks like this:
//friction to velX and and gravity to velY (horizontal and vertical values) mc_frombie.velX *= friction; mc_frombie.velY += gravity; // mc_frombie.grounded = false;
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 colisionCheck
.
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 mc_frombie.jumping
to false
.
Bottom means you’re standing on the ground. So mc_frombie.grounded
is set to true
and 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:
for (var i = 0; i < arr_colidable.length; i++) { // dir = colisionCheck(mc_frombie, arr_colidable[i]); // if (dir === "left" || dir === "right") { mc_frombie.velX = 0; mc_frombie.jumping = false; } else if (dir === "bottom") { mc_frombie.grounded = true; mc_frombie.jumping = false; } else if (dir === "top") { mc_frombie.velY *= -1; //if you hit the top then he protects his head (you scared him) //jumping resets this player_duck("ouch"); // } }
After that we manage velY
if he’s on the ground (not jumping anymore, above collision with ground took place).
Just reset/set velY
to 0 (default state):
if(mc_frombie.grounded){ mc_frombie.velY = 0; }
FINALLY, we need to set the player’s x
and y
to the calculated values.
Simply put:
mc_frombie.x += mc_frombie.velX; mc_frombie.y += mc_frombie.velY;
The last bit manages the player falling off the screen and dying, or walking off the right and winning:
//Player death //fell off stage if(mc_frombie.y > (num_stageHeight + mc_frombie.height)){ player_die(); }; //Player went to next screen if(mc_frombie.x> (num_stageWidth + mc_frombie.width)){ if(bool_lastpanel){ player_win(); }else{ console.log("next panel"); }; };
That’s it! The entire thing looks like this:
function event_movement_ticker(event) { //key presses //jump //make the jump - set to values - reset after if (bool_jumpDown && !mc_frombie.jumping && mc_frombie.grounded) { // mc_frombie.jumping = true; mc_frombie.grounded = false; mc_frombie.ducking = false;//reset ducking also if up is pressed // mc_frombie.velY = -mc_frombie.speed * mc_frombie.jumpHeight; //reset bool_jumpDown = false; bool_keyDown = false; } //reset the jump height while in the air //if done above sometimes it doesn't reset if(!bool_jumpDown && mc_frombie.jumping && !mc_frombie.grounded){ mc_frombie.jumpHeight = 1.5; }; //start ducking - ducking is in the ticker because it needs to trigger RIGHT AWAY if ((key.isPressed("down") || key.isPressed("s")) && (!mc_frombie.jumping && mc_frombie.grounded)) { //duck player_duck("duck"); } //unduck - only if also height is less than default so that no conflict with other gotoAndStop labels... if(!mc_frombie.ducking && mc_frombie.height<110){ mc_frombie.height = 110; mc_frombie.gotoAndStop("walk"); }; //left/right movement if ((key.isPressed("left") || key.isPressed("a"))) { if (mc_frombie.velX > -mc_frombie.speed) { mc_frombie.velX-=mc_frombie.speed; } } //stop player movement if ((key.isPressed("right") || key.isPressed("d"))) { // if (mc_frombie.velX < mc_frombie.speed) { mc_frombie.velX+=mc_frombie.speed; } // } //friction to velX and and gravity to velY (horizontal and vertical values) mc_frombie.velX *= friction; mc_frombie.velY += gravity; // mc_frombie.grounded = false; // //HIT----- for (var i = 0; i < arr_colidable.length; i++) { // dir = colisionCheck(mc_frombie, arr_colidable[i]); // if (dir === "left" || dir === "right") { mc_frombie.velX = 0; mc_frombie.jumping = false; } else if (dir === "bottom") { mc_frombie.grounded = true; mc_frombie.jumping = false; } else if (dir === "top") { mc_frombie.velY *= -1; //if you hit the top then he protects his head (you scared him) //jumping resets this player_duck("ouch"); // } } //END HIT----- //if on the ground then set velY to default state if(mc_frombie.grounded){ mc_frombie.velY = 0; } //now set the actual x and y to calculated values mc_frombie.x += mc_frombie.velX; mc_frombie.y += mc_frombie.velY; // //Player death //fell off stage if(mc_frombie.y > (num_stageHeight + mc_frombie.height)){ player_die(); }; //Player went to next screen if(mc_frombie.x> (num_stageWidth + mc_frombie.width)){ if(bool_lastpanel){ player_win(); }else{ console.log("next panel"); }; }; }
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)
Hi, thanks for your website, some good stuff on here. I am playing with flash html5 canvas and have an interactive graphc where I am trying to open a youtube window in a new window, on top of my graphic. Any tips would be great. Im new to javascript. thanks!
Unassuming Question:
Ticker timer – Choppy animations seem abound with createJS goodness, tried using delta time, mathrounding movement, etc etc unless i smash the ticker refresh to some crazy amount there is always joddery animation….
SO…
Have you come across this, and how did you smash it ?
Regards…..