Jumping
From EGMSWiki
|
Simple Jumping
Prepping your hero for flight!
Review keyboard controls by revisiting the Mini Game Project's keyboard control section.
In the Mini Game Project you learned how to make your character move left and right, but we want to add one small bit of realism to our hero before moving on to jumping. First, make sure that your hero's registration point is in the center of its movie clip.

If your hero's registration point is not in the center, watch the below movie clip to see how to fix it.

Also, all of this trouble can be fixed when you convert your drawing to a movie clip if you pay attention to the registration area.

Now that your hero's registration, or pivot, point is in the center, notice how the hero realistically turns left and right with the help of the _xscale property.
Below is example code to be placed on Frame 1 in the main timeline:
stop();
hero.onEnterFrame = function(){
if(Key.isDown(Key.RIGHT)) {
this._x += 4;
this._xscale = -100;
}
if(Key.isDown(Key.LEFT)) {
this._x -= 4;
this._xscale = 100;
}
}
Taking Flight!
Now that our hero can realistically move left and right, let's make our hero jump! First, a little science.
When our hero jumps, he will start at a specific speed - let's say 6 pixels. As our hero ascends, gravity should slow our hero down, eventually stopping his upward momentum, and then bring our hero back down to the ground. The diagram below illustrates a jump cycle. Notice the red numbers surrounding the jump that illustrate how fast our hero goes. The black numbers denote the hero's x coordinate. Our hero starts out fast, slows down, plateaus, and then reverses velocity. That is what we will accomplish in ActionScript.

So now we need to know two things, how fast we want our hero to take off, and how much gravity is going to slow our hero's progress. In the above example, our hero would take off at 6 pixels, and gravity would slow our hero down 3 pixels at a time. That is not a lot of air time. In one of the below examples, if you make your hero accelerate at 30 pixels, but make gravity only subtract 2 pixels of velocity at a time, it will take 15 loops or math problems before your hero's velocity becomes zero, plateaus, and then starts to come back down due to negative velocity. So, these two numbers - gravity and initial acceleration - are critical for how you want your gravity to work in your game. To illustrate this point, examine the two flash files below with the exact same initial acceleration, BUT with different gravity numbers.
Below is the code that makes this all happen. As you read the code, look back at the Jump Cycle diagram to understand the effects of acceleration and gravity.
Warning: position your hero so it is touching the ground before you run your Flash file. If you don't, the hero will hover above the ground.
FINISHED CODE FOR SIMPLE JUMPING - FRAME 1, MAIN TIMELINE
stop();
//horizonal walking speed
_global.landspeed = 4;
//jump related variables
//Variable to know whether our hero is Jumping or not
_global.isJumping = false;
//Velocity as mentioned in the Jump Cycle diagram
_global.velocity = 0;
//Tweak this value along with gravity for interesting results
_global.velocitymax = 30;
//Gravity (acceleration) as mentioned in the Jump Cycle diagram
_global.gravity = 2;
//The Y value my hero starts on
_global.startY = _root.hero._y;
hero.onEnterFrame = function(){
if(_global.isJumping == true){
//If hero is jumping, move hero's y coordinate
this._y -= _global.velocity;
_global.velocity -= _global.gravity;
if(this._y >= _global.startY){
//If hero falls on or below the ground, bring hero back to ground level and turn off Jumping
this._y = _global.startY;
_global.isJumping = false;
//Turn walking speed back to full blast
_global.landspeed = 4;
}
} else {
if(Key.isDown(Key.SPACE)){
//Hero is jumping, velocity is turned on, walking speed slowed down
_global.isJumping = true;
_global.velocity = _global.velocitymax;
_global.landspeed = 2;
}
}
if(Key.isDown(Key.RIGHT)) {
this._x += _global.landspeed;
this._xscale = -100;
}
if(Key.isDown(Key.LEFT)) {
this._x -= _global.landspeed;
this._xscale = 100;
}
}FINISHED SIMPLE JUMPING FLASH DEMO
If you have problems implementing the code, or want to play with the original, you can download it here.
Advanced Jumping with Platforms
Adding walking momentum.
Your hero can walk, turn left, turn right, and jump, but the hero's walking code can be even more realistic. Look at the image below to see how your hero moves currently and how it can look more realistic with acceleration.

When the gas pedal is pressed in a car, does the car automatically move 50 miles per hour? No, it starts at 15, then 25, 35, 45, and then finally 50. It gradually accelerates up to that velocity, or in our case, our "speed limit". Below is the code from the finished Simple Jumping section modified to allow for acceleration.
stop();
//horizonal walking speed related variables
//This is your starting walking speed
_global.landspeed = 0; //changed to zero from previous revision
//This is your speed limit
_global.landspeedmax = 25;
//This is used to slowly accelerate your hero up to the speed limit
_global.acceleration = .85;
//jump related variables
//Variable to know whether our hero is Jumping or not
_global.isJumping = false;
//Velocity as mentioned in the Jump Cycle diagram
_global.velocity = 0;
//Tweak this value along with gravity for interesting results
_global.velocitymax = 30;
//Gravity (acceleration) as mentioned in the Jump Cycle diagram
_global.gravity = 2;
//The Y value my hero starts on
_global.startY = _root.hero._y;
hero.onEnterFrame = function(){
if(_global.isJumping == true){
//If hero is jumping, move hero's y coordinate
this._y -= _global.velocity;
_global.velocity -= _global.gravity;
if(this._y >= _global.startY){
//If hero falls on or below the ground, bring hero back to ground level and turn off Jumping
this._y = _global.startY;
_global.isJumping = false;
}
} else {
if(Key.isDown(Key.SPACE)){
//Hero is jumping, velocity is turned on
_global.isJumping = true;
_global.velocity = _global.velocitymax;
}
}
_global.landspeed *= _global.acceleration; //NEW CODE
if(Key.isDown(Key.RIGHT)) {
//NEW CODE
if (_global.landspeed < _global.landspeedmax) {
_global.landspeed++;
}
this._x += _global.landspeed;
this._xscale = -100;
}
if(Key.isDown(Key.LEFT)) {
//NEW CODE
if (_global.landspeed > -_global.landspeedmax) {
_global.landspeed--;
}
this._x += _global.landspeed;
this._xscale = 100;
}
//NEW CODE
if (Math.abs(_global.landspeed) < 1 ) {
//if my hero's speed has slowed down between
//a range of -1 to 1, make the speed stop
//Math.abs (absolute value) statement above would be the same
//as stating if(_global.landspeed > -1 && _global.landspeed < 1)
_global.landspeed = 0;
}
}
Several new variables were created such as _global.landspeedmax and _global.acceleration. The _global.landspeed was also set to zero, allowing it to build up to its speed limit, instead of simply being set to it like in the previous version. Any code which set _global.landspeed statically was removed as well. The line _global.landspeed *= _global.acceleration; was added to make the acceleration more gradual. Two opposite blocks of code were added in the Key.LEFT and Key.RIGHT sections. This code allows the hero to accelerate until he reaches the speed limit. NOTE: Both Key.LEFT and Key.RIGHT blocks now contain the exact same line:
this._x += _global.landspeed;Finally, a new block of code has been added at the very bottom which checks to see if our hero is "idle". It uses a math function called absolute value to check and see if the speed is between -1 and +1. If it is, the current speed is set to zero. Below is a flash file showing the changes.
Note that our hero still does a simple jump, meaning that hero always lands at the same horizontal level. We now need to use some collision detection to make our hero "hit" the earth.
Colliding with platforms.
- Review the Collision Detection topic for a detailed look at collision detection.
Our first order of business is to look at some code. The following two blocks of code stop hero from falling any further downwards than the horizontal level hero jumped from.
//The Y value my hero starts on _global.startY = _root.hero._y;
and
if(this._y >= _global.startY){
//If hero falls on or below the ground, bring hero back to ground level and turn off Jumping
this._y = _global.startY;
_global.isJumping = false;
}
After removing those two sections of code from our file, the results below show that we fall like a lead balloon now!
Now, let's add some collision detection.
if (!_root.ground.hitTest(this._x, this._y, true) && !_global.isJumping) {
//hero isn't on the ground and isn't jumping - hero fell off a platform or is in freefall
this._y += 6;
}
The code above needs to be added inside your hero.onEnterFrame code. The above code tests the following condition, "If hero isn't touching the ground and hero isn't jumping either". The only way that the hero wouldn't be touching the ground or jumping would be that he is falling, or in our case, should be falling, so that is why the code inside makes him fall 6 pixels at a time. Once the hero touches the ground again this code will stop running. The below Flash file shows this code in action. Notice that the hero starts in a freefall, and stops falling once he reaches the ground. At that point, if the hero falls off a platform, he will actually fall instead of floating as before.
Our next area of trouble will be completing our landing after jumping. We need a way to test if the hero collides with a platform while falling, so we will create a falling variable called isFalling. This variable will function much like isJumping. How will we know when he hero is falling? Look back at the Jump Cycle image above. When he reaches the peak of the jump, velocity starts to become negative. With these new changes in effect, our code now looks like this:
stop();
//horizonal walking speed related variables
//This is your starting walking speed
_global.landspeed = 0;
//This is your speed limit
_global.landspeedmax = 25;
//This is used to slowly accelerate your hero up to the speed limit
_global.acceleration = .85;
//jump related variables
//Variables to know whether our hero is Jumping or Falling
_global.isJumping = false;
_global.isFalling = true;
//Velocity as mentioned in the Jump Cycle diagram
_global.velocity = 0;
//Tweak this value along with gravity for interesting results
_global.velocitymax = 30;
//Gravity (acceleration) as mentioned in the Jump Cycle diagram
//more gravity (5.0)
//less gravity (.01)
_global.gravity = 2;
hero.onEnterFrame = function(){
if (!_root.ground.hitTest(this._x, this._y, true) && !_global.isJumping) {
//hero isn't on the ground and isn't jumping - hero fell off a platform or is in freefall
//changing the number below can make hero fall faster or slower based on conditions above
this._y += 6;
}
if (_root.ground.hitTest(this._x, this._y, true) && _global.isFalling) {
//hero is in the falling section of a jump and finally lands back on terra firma
//reset jump counter back to default
_global.velocity = _global.velocitymax;
_global.isJumping = false;
_global.isFalling = false;
}
if(_global.isJumping == true){
//If hero is jumping, move hero's y coordinate
this._y -= _global.velocity;
_global.velocity -= _global.gravity;
if (_global.velocity < 0) {
//hero is starting the descent down
_global.isFalling = true;
}
} else {
if(Key.isDown(Key.SPACE)){
//Hero is jumping, velocity is turned on
_global.isJumping = true;
_global.velocity = _global.velocitymax;
}
}
_global.landspeed *= _global.acceleration;
if(Key.isDown(Key.RIGHT)) {
if (_global.landspeed < _global.landspeedmax) {
_global.landspeed++;
}
this._x += _global.landspeed;
_root._x -= _global.landspeed;
this._xscale = -100;
}
if(Key.isDown(Key.LEFT)) {
if (_global.landspeed > -_global.landspeedmax) {
_global.landspeed--;
}
this._x += _global.landspeed;
_root._x -= _global.landspeed;
this._xscale = 100;
}
if (Math.abs(_global.landspeed) < 1 ) {
//if my hero's speed has slowed down between
//a range of -1 to 1, make the speed stop
//Math.abs (absolute value) statement above would be the same
//as stating if(_global.landspeed > -1 && _global.landspeed < 1)
_global.landspeed = 0;
}
}
The below Flash file shows this code in action. Notice that the hero can now jump and safety land on any level you have placed a platform on. There are two small problems, though - one, he doesn't sit "on top" of the platforms, and two, when you try to jump to the last platform the hero often falls right through it.
To fix the way the hero sits on a platform, we need to adjust his registration point again. We still want hero to pivot left and right, but we want to place the registration point at the bottom of hero's movieclip. This will help the collision detection more quickly stop his downward velocity.

Typically, this is easily accomplished by changing the Y coordinate to the negative height of your movieclip's drawing.
As for hero falling right through the last platform, we need to enforce a vertical speed limit like we have a horizontal speed limit. In science, this is called terminal velocity. The below code snippet shows you where to place the terminal velocity code.
if(_global.isJumping == true){
//If hero is jumping, move hero's y coordinate
this._y -= _global.velocity;
_global.velocity -= _global.gravity;
if (_global.velocity < 0) {
//hero is starting the descent down
_global.isFalling = true;
}
if (_global.velocity < -_global.velocitymax) {
//this caps (or sets) the hero's terminal velocity
_global.velocity = -_global.velocitymax;
}
} else {
The last if-statement sets a terminal velocity. Whatever velocity we started out at, i.e. 30, will also be used to set the maximum downward velocity, -30. If our hero's velocity reaches -35, which is less than -30, it will be reset at -30.
So, here is the file thus far. The hero should sit better on the platforms. Sometimes, adjusting the Y coordinate of drawn platforms can help him land on the platforms better. Look at the interval you have him jumping at, and try to adjust the platform's position to collide with that number perfectly. The platforms should completely work, but when the hero falls, the game doesn't end.
Welcome to the Dead Zone!
In this step, we will finish our Advanced Jumping topics by adding a deadzone, or an area that will cause a play to get a game over screen.
First, let's create the deadzone. Below is an example of a deadzone (the green block). A deadzone's only requirements are that it should be as wide as your Flash stage and be right below the Flash stage, out of sight during gameplay. NOTE: Don't forget to give it an instance name! This tutorial will use the instance name deadzone.

We now need to add code so that if the hero falls off screen and collides with the deadzone, something will happen. Here is the particular piece of code that will do all the magic.
hero.onEnterFrame = function(){
if(_root.deadzone.hitTest(this)){
//If the hero hits this movieclip called deadzone, which is below the stage's boundary
//go to frame 2, the "You're Dead" frame
_root.gotoAndStop("dead");
} else {
//"I'm not dead yet!"
if (!_root.ground.hitTest(this._x, this._y, true) && !_global.isJumping) {
//hero isn't on the ground and isn't jumping - hero fell off a platform or is in freefall
//changing the number below can make hero fall faster or slower based on conditions above
this._y += 6;
}
So, right after the onEnterFrame, we add an if statement to test whether the hero has collided with the deadzone. Now all the code that controls the hero will only work if he isn't dead. NOTE: We have just added another open curly brace. Make sure to add the closing curly brace at the bottom of your code. Remember, the deadzone is off screen, so the only way that the hero would collide with it is if hero fell to an untimely death. If he does touch the deadzone, Flash goes to frame two, which I have given a frame label of dead. On frame two, I have typed You're Dead and placed a button that can be clicked to that takes the player back to frame one to start the whole game again. Below is a Flash file of the current progress.
We still have one final problem. Sometimes the hero falls to an untimely death and nothing happens. The following Flash file will shed some light on to the subject.
I have intentionally moved the deadzone as well as frame 2's contents to the screen to show you what is happening. Move the hero around and notice how the deadzone and the Replay button do not follow hero. This is our problem. Remember in step 2 when we talked about hero being on an escalator and maintaining a proper speed? Well, the deadzone isn't keeping up with the escalator. We need to make sure that when hero moves, the deadzone follows as well. Below shows the fixed code section.
if(Key.isDown(Key.RIGHT)) {
if (_global.landspeed < _global.landspeedmax) {
_global.landspeed++;
}
this._x += _global.landspeed;
deadzone._x += _global.landspeed;
_root._x -= _global.landspeed;
this._xscale = -100;
}
if(Key.isDown(Key.LEFT)) {
if (_global.landspeed > -_global.landspeedmax) {
_global.landspeed--;
}
this._x += _global.landspeed;
deadzone._x += _global.landspeed;
_root._x -= _global.landspeed;
this._xscale = 100;
}
Notice after that small fix, the deadzone is keeping up with hero now. Now, if we can just find a way to get back to the button and text when the hero dies, we will be done.
Notice that in the code snippet above that _root._x changes. That is the position of the entire Flash stage, including the frame 2 text and Replay button. If we could make that _x reset to zero when hero dies, we should be able to see the button and text. Below is the code snippet with the new code.
hero.onEnterFrame = function(){
if(_root.deadzone.hitTest(this)){
//If the hero hits this movieclip called deadzone, which is below the stage's boundary
//go to frame 2, the "You're Dead" frame
_root.gotoAndStop("dead");
_root._x = 0;
} else {
//"I'm not dead yet!"
In the code that sends us to the You're Dead frame, a line was added that moves _root._x back to zero. Below is the finished code for the Advanced Jumping topic.
FINISHED CODE FOR ADVANCED JUMPING - FRAME 1, MAIN TIMELINE
stop();
//horizonal walking speed related variables
//This is your starting walking speed
_global.landspeed = 0;
//This is your speed limit
_global.landspeedmax = 15;
//This is used to slowly accelerate your hero up to the speed limit
_global.acceleration = .85;
//jump related variables
//Variables to know whether our hero is Jumping or Falling
_global.isJumping = false;
_global.isFalling = true;
//Velocity as mentioned in the Jump Cycle diagram
_global.velocity = 0;
//Tweak this value along with gravity for interesting results
_global.velocitymax = 12;
//Gravity (acceleration) as mentioned in the Jump Cycle diagram
//more gravity (5.0)
//less gravity (.01)
_global.gravity = .5;
hero.onEnterFrame = function(){
if(_root.deadzone.hitTest(this)){
//If the hero hits this movieclip called deadzone, which is below the stage's boundary
//go to frame 2, the "You're Dead" frame
_root.gotoAndStop("dead");
_root._x = 0;
} else {
//"I'm not dead yet!"
if (!_root.ground.hitTest(this._x, this._y, true) && !_global.isJumping) {
//hero isn't on the ground and isn't jumping - hero fell off a platform or is in freefall
//changing the number below can make hero fall faster or slower based on conditions above
this._y += 6;
}
if (_root.ground.hitTest(this._x, this._y, true) && _global.isFalling) {
//hero is in the falling section of a jump and finally lands back on terra firma
//reset jump counter back to default
_global.velocity = _global.velocitymax;
_global.isJumping = false;
_global.isFalling = false;
}
if(_global.isJumping == true){
//If hero is jumping, move hero's y coordinate
this._y -= _global.velocity;
_global.velocity -= _global.gravity;
if (_global.velocity < 0) {
//hero is starting the descent down
_global.isFalling = true;
}
if (_global.velocity < -_global.velocitymax) {
//this caps (or sets) the hero's terminal velocity
_global.velocity = -_global.velocitymax;
}
} else {
if(Key.isDown(Key.SPACE)){
//Hero is jumping, velocity is turned on
_global.isJumping = true;
_global.velocity = _global.velocitymax;
}
}
_global.landspeed *= _global.acceleration;
if(Key.isDown(Key.RIGHT)) {
if (_global.landspeed < _global.landspeedmax) {
_global.landspeed++;
}
this._x += _global.landspeed;
deadzone._x += _global.landspeed;
_root._x -= _global.landspeed;
this._xscale = -100;
}
if(Key.isDown(Key.LEFT)) {
if (_global.landspeed > -_global.landspeedmax) {
_global.landspeed--;
}
this._x += _global.landspeed;
deadzone._x += _global.landspeed;
_root._x -= _global.landspeed;
this._xscale = 100;
}
if (Math.abs(_global.landspeed) < 1 ) {
//if my hero's speed has slowed down between
//a range of -1 to 1, make the speed stop
//Math.abs (absolute value) statement above would be the same
//as stating if(_global.landspeed > -1 && _global.landspeed < 1)
_global.landspeed = 0;
}
}
}
FINISHED CODE FOR ADVANCED JUMPING - FRAME 2, MAIN TIMELINE
replay.onRelease = function() {
gotoAndStop("gamestart");
}
FINISHED ADVANCED JUMPING FLASH DEMO
If you have problems implementing the code, or want to play with the original, you can download it here.
Update the Wiki
- Upload the assets (.SWF and .FLA) you created to your Team page if you are working on a Team game, or to your "My Projects" page if you are working alone.
Update the Blog
- Write a Blog post about this topic, share your learning experience!
Related Links and Tutorials
- Browse the MyGLife.org Flash Tutorials list for more tutorials, information and links!
Search the Web for more information
Here are some search results on Flash ActionScript programming:
- Google results for "flash & platform & tutorial".
- TeacherTube results for "flash"
- Ask.com results for "actionscript & platform & tutorial".
