WARNING: This Platformer Tutorial is not to be copy and pasted and will not work if tried. This will require you to read the code, read the description of the code, play around with the code and repeat those steps until you've figured out exactly how it works.
Set Up
The Hero: Draw a box (any size will do but not too big in relative to how large you think the world will be). Convert the box into a movieclip with the co-ordinates set to center-bottom.
The Bounds: Create an empty movieclip and put it on the stage, go into its properties and write in "0" for the _x and _y inputs. This sets the clip at the top-left of the stage (this is done to match the internal co-ordinates of the movieclip with the stages co-ordinates). Go into the movieclip and draw floors, walls, ceilings, little floaty platforms, go to town but use the box tool (we want straight perfectly level lines....for now). Once youre done with that give the movieclip the instance name "bounds".
You got that done? Ok. Next up some actual code.
Coding
All the code is going to be inside the hero's actions so get in there.
The Following is the full code for this tute (i've intentionally added 3 syntax errors to try and prevent straight copy and pasting).
All the code descriptions are following //'s (.....but you knew that).
onClipEvent (load) {
jumpkey = 65;
rightkey = 39;
leftkey = 37;
// those three are just keycodes for A, Right Arrow, Left Arrow. I often find i want to change keys mid-production of a game so this is a helpful habit.
fall = true;
jump = false;
// These should be obvious. Just to make this simpler on yourself you should place the hero not touching any of the bounds so he starts falling when you play.
descend = 0;
// descend is switch variable like fall and jump but it requires more than 2 settings so we use a number rather than true/false. Descend makes hero come as close to the bounds as possible without passing them for jumping and falling (will make more sense later).
walkdescend = 0;
// the same as descend but rather than for falling and jumping for walls when moving right/left
walk = 10;
maxspeed = 15;
dropspeed = 5;
resetdropspeed = 5;
jumpspeed = 0;
//omg speeds! jumpspeed and dropspeed are not static, theyre changed midgame to provide realistic looking gravity.
bounds = _root.bounds;
// this one is just making a variable for bounds so we dont have to type quite so much and if we want to change the location of bounds (put it inside another movieclip) we can.
hei = 0;
halfhei = 0;
halfwid = 0;
quartwid = 0;
// these 4 hold the hero's height, half height, half width and quarter width.
}
onClipEvent (nterFrame) {
hei = Math.floor(_height);
halfhei = Math.floor(_height/2);
halfwid = Math.floor(_width/2);
quartwid = Math.floor(_width/4);
// we meet again and so soon. every frame we set the hero's various heights and widths which we'll use for hitTesting. _width grabs the hero's width and _height grabs the hero's height which we then divide as needed and round down to the nearest whole number using Math.floor to make it easy on hitTest.
//if you put graphics inside the hero clip or in another clip and grabbed the graphics heights and widths you could dynamically change the hitTest bounds to fit the animations in real-time (havent thoroughly tested this situation so it may cause issues).
if (Key.isDown(rightkey)) {
//if you dont know what this does then you need to stop reading this and catch up on the more general actionscript tutorials that come with flash
if (walkdescend == 0) { // if walk desend hasnt been initiated
if (bounds.hitTest(_x+halfwid+walk, _y, true)) {
walkdescend = 1;
//this finds the dot where hero's x + half of his width (the furthest right bound of hero) + walk (the furthest right of where the hero will be if he walks) and y (heros feet) is and tests if that dot is hitting the bounds. if it is we initiate walkdescend 1.
//Note: notice we hitTest before moving anything, its more effective than the reactive style of testing after movement. feel free to try it both ways though.
} else if (bounds.hitTest(_x+halfwid+walk, _y-halfhei, true)) {
walkdescend = 2;
//same as the last if but we've subtracted half the hero's height so if we have a bound that doesnt hit at feet level (jumping) we'll still catch the hit
} else if (bounds.hitTest(_x+halfwid+walk, _y-hei, true)) {
walkdescend = 3;
// and once more for the top of the hero
} else {
_x += walk;
//you didnt hit anything so youre free to move. hizah!
}
}
if (walkdescend == 1) {
//ok so you were about to walk into a wall at foot level, if we had moved the hero he would have gone through the wall but if we dont move him it will look odd like a forcefield around the wall so we need to ease him into the wall
while (!bounds.hitTest(_x+halfwid+1, _y, true)) {
// while the hero IS NOT (designated by the !) hitting the dot at the hero's feet (_y) and 1 pixel infront of the right of the hero (_x+halfwid+1) we...
_x++;
//...move the hero 1 pixel to the right.
//NewbNote: while is a loop. loops are different from most code because they do nothing else until theyre complete. if a loop never ends it will crash the flash player.
}
walkdescend = 0;
//and the second we get out of that loop we put walkdescend back to zero
}
if (walkdescend == 2)
while (!bounds.hitTest(_x+halfwid+1, _y-halfhei, true)) {
_x++;
}
walkdescend = 0;
}
//same deal except halfway up the heros body
if (walkdescend == 3) {
while (!bounds.hitTest(_x+halfwid+1, _y-hei, true)) {
_x++;
}
walkdescend = 0;
}
//and again...we do this so many times at different heights so that theres little to no chance that the hero will be able to penetrate the bounds
}
[Running out of characters...continued next post]