Sidescrolling Platformer ~Part 4~ Gravity and Jumping

In Part 3 we took a simple, scrollable background and added a layer of realistic player interaction by adding collisions and smoother movement. But we didn’t have the time to finish our player interaction by adding gravity and jumping, so that’s what we’ll do in this part. We are also going to add a few small tweaks to earlier game mechanics so that everything runs better.

Get ready for another great tutorial. I put more time into this one than I expected to.

Gravity

Adding gravity is actually reallyeasy. If you have any experience with Physics, you know that gravity causes an acceleration on objects. And an acceleration is nothing more than a change in speed. In an ideal situation on earth, an object’s velocity downwards increases by 9.8 meters per second for every second that it’s falling. So in our game, we will increase the speed of the player by a certain number for every frame that he is falling.

Q: How do we know if the player is falling?

A: Check if the downBumping variable is equal to false.

Q: How do we update the player’s speed so he falls faster each frame?

A: Increase the ySpeed variable in the main loop.

That’s pretty much all we need to know in order to implement the gravity. So let’s jump right into the code.

First, one small correction to our code. When we defined the scrollX, scrollY, xSpeed, and ySpeed variables in the last tutorial, we gave them the type int. This means that they can only be integers (whole numbers — not decimals). But we want to have a more exact representation of our speed and location, so let’s change their types to Number instead, so that they can have decimal values as well as integer values.

Also create a new variable which we will set with the strength of our gravity. A value of 1.5 means that our player’s ySpeed will be increased by 1.5 pixels per frame, which happens 30 times per second.

var gravityConstant:Number = 1.5;

Time to add the gravity code. In our main game loop, we already have a conditional (an “if” statement) which checks if downBumping is true. We can piggyback off of this existing conditional to check if downBumping is NOT true, by adding an “else” statement at the end.

Update the old downBumping conditional in the loop function so it looks like this:

Run your code… and voila! Gravity! I told you it was easy! If you want stronger, more realistic gravity, all you need to do is increase your gravityConstant, maybe to 2 or 2.5. And if you are programming a platformer on the moon, just decrease the gravityConstant.

(Click on the preview below to activate it, then use the arrow keys to move around)

Jumping

The gravity is working greatly, but we can’t get a real feel for the final game mechanics without a good jumping system. Right now we can just fly up and down freely. In the final game, neither holding the up arrow nor the down arrow will do anything. So we can actually delete the code we’ve been using so far to move up and down. (Don’t delete the code to move left and right — we still need that).

Delete (or just comment-out) the upPressed and downPressed conditionals:

If you compile and run your game now, you should be able to run left and right, but you can’t do anything to oppose the gravity pulling down on you.

Now we can safely program the jumping mechanic without being interfered by our earlier movement code. First add another variable to your program, which will determine how powerful your character’s jump will be.

var jumpConstant:Number = -25;

Similar to the gravity constant we added before, we defined the jump power in a variable so that we can easily change the physics of the game later on by updating a single variable. Notice how much larger this value is than the gravity? This is because we are not going to be constantly updating this variable 30 times per second. Instead, we are going to set the ySpeed to this jumpConstant all at once, which will instantly give the player a big boost in speed upwards A.K.A. a jump!

We wanted gravity to affect the player only when he is not on the ground, but we wan the player to be able to jump only if he is on the ground. So we can use the same conditional as before, but just put the jumping code in the “if” part, instead of the “else” part.

As simple as that looks, this is the only bit of code you need to add to get the jumping mechanic up and running. I’m sure there are different ways to program jumping which will give you slightly different results, but this one is as simple as it is effective. Run your game and see the magic.

Just like with the gravityConstant, you can update the jumpConstant to get different effects. Want to jump super high? Just crank up the jump power. Remember to play around with all of the constants to try to get a good balance. For example, if you turn down gravity you will need less jump power to achieve the same jump height.

Other Small Tweaks

I’m going to take this time to change a couple other small things which I’ve been meaning to fix. I’m not going to explain them in too much detail — they are small, simple tweaks, which will polish up the game mechanics a bit, and clean up our code a little.

Bouncy Floors?

Before I end this post, let’s fix one more thing: When was the last time you played a platformer with bouncy floors?? Maybe that’s your million-dollar idea, but otherwise it’s probably a good idea to take the bounce out of your step. It’s extremely easy to do, and can be done within the same conditional that we’ve been modifying this entire post.

Friction

First up is something trivial, just renaming the friction variable so that it conforms to our new standard variable names: “frictionConstant“. You don’t need to do this, but so far we have named all other variables similarly that represent a constant value which we can change later to modify the game physics. If you decide to change your variable name too, just remember to also change everywhere else in your code which you use friction so that it matches the new name. Also, I updated my frictionConstant from 0.95 to 0.9, so that my player slows down faster.

Minimum Speed

Next, I set a minimum possible xSpeed for the player. Friction slows the player down, but it never stops the player completely. I just decided to clean up the game mechanics a little bit by setting the x speed to zero whenever friction slows it down to less than 0.5.

In the game loop, below where you multiply the x and y speeds by the frictionConstant, add the following code:

if(Math.abs(xSpeed) < 0.5){
xSpeed = 0;
}

Simply put, this checks if the absolute value of the xSpeed is less than 0.5, and if it is, sets the new value to 0.

Maximum Speed

Currently friction is the only thing keeping us from running left and right at extreme speeds. But I still think it is too fast for the platformer I want to make. So lets create a maxSpeedConstant which will be equal to the highest possible xSpeed the player can run with.

var maxSpeedConstant:Number = 18;

After playing around with the constants a bit, I set mine to 18, but you can set yours to whatever you like. Before you do, implement the following code to set the xSpeed to this maxSpeedConstant whenever it exceeds it. Above the friction lines, add this conditional:

When the player is moving right, the xSpeed gets set to a maximum of the maxSpeedConstant. If he is running to the left (the negative x-direction), it will be set to a maximum of the maxSpeedConstant multiplied by -1.

Customizing your physics!

We now have a grand total of fiveconstants which combined will dictate how the physics of your game works.

Here is a recap of what they all do, along with the final values I’ve chosen at this point.

var speedConstant:Number = 4;

Sets how fast you move and accelerate.

var frictionConstant:Number = 0.9;

Sets how fast you come to a stop.

var gravityConstant:Number = 1.8;

Sets how fast you are pulled downwards. Affects jump height and fall speed.

var jumpConstant:Number = -35;

Sets how fast you jump upwards. In combination with gravity, this determines your jump arc.

var maxSpeedConstant:Number = 18;

Sets how fast your maximum run speed is.

I fully encourage you to play around with the numbers to create a unique game experience!

That’s all, folks!

(Click on the preview below to activate it, then use the arrow keys to move around)

Hooray! Our platformer game finally acts like a platformer game!

Here’s the source code, in case you’re getting any errors and want to double-check your code. Or if you’re just too lazy to type everything yourself ;)

What’s next, you ask? More awesomeness. In the next tutorial, we will probably spice up our game with a layer of custom graphics, AND a parallax scrolling background! We might also add support for multiple levels, accessible by reaching a level-exit.

Please subscribe, share this post, or leave me a comment if you appreciate all the time I’ve put into this series :)

That’s definitely a good question. I can explain pausing in detail in a future post, but here’s a quick walk-through of what to do. Create a Boolean variable called gamePaused, or something similar. Then inside your loop function, put all of the code inside a big conditional if(gamePaused == false) { // all of the code we currently have in the loop function goes here }. This will make the main game loop only run if the gamePaused variable isn’t true. Now whenever you want to pause the game, just set gamePaused=true, and to unpause set gamePaused=false. You could do this by clicking on an icon, or by inside the keyUpHandler function, where you could test if the “P” key has been pressed and released.

My player is not colliding with the floor very well; it seems as if his whole body goes through the ground except for his head. I tried to change my character’s graphic into a circular character, but then the hitTest said that it was hitting the ground a couple pixels under the ground. Any suggestions?

Hmmm…. I can’t imagine why this is happening. In a normal situation, if you set each of the bump points to the player’s position, plus or minus half of the player’s width or height, the player should collide with the walls. Also, make sure that the walls are thick enough so that the player doesn’t “slip through” without the hit being detected.

I fixed it by using your player and then editing it to make my own one :) In future tutorials, are you going to make it so the guy can walk on curved surfaces? I tried bending a whole bunch of platforms, but it made him go through the floor as he was going up the incline.

1: my school is too cheap(or rather, they can’t afford the outrages prices) to let me upgrade to CS5, so i use CS3, so your source-code files won’t work for me, could you add an pure textfile version of them?

2: I’m having a problem with my player falls off the game ( the run-though-walls problem), that be in all directions.

Ben I`ve been following your tutorial. Have you already played Culmunation or Armed with Wings 1,2,3? they can zoom in or out the camera view of the player…. I think papervision can do that… I will be making my first rpg game… those games are my inspiration and your tutorial is my first step. Do you have any suggestion or tips regarding to those kind of rpg games? if you dont mind i can give you my email so that I could ask you more :P powerlogic1992@gmail.com

I’ve played Armed with Wings before and it’s definitely a great game. Are you looking for tips regarding the RPG elements of the game, or regarding a more complex camera system (that supports zooming, etc)?

Hey Ben i need help, i am using this to make and i can’t seem to figure out whats wrong. so i have everything code wise correct, but when i start my game the player doesn’t move in the map but when i am out of it (the white abyss) he moves just like your game. help is greatly appreciated, thanks.

Ben,
Ive found your tutorial on making a platformer the best on the web. It’s easy to understand and follow. I was wondering if you can explain how to make the player show a falling animation after he reaches his peak jump height and a landing animation everytime he lands. Something similar to the game fancy pants or gangsta bean. Most games have the jump and fall animation but I noticed that the best ones have that landing animation that always seem to look awesome in my opinion. Ive been following your tutorials and I can’t wait for the next ones. Thanks for all your help. Really appreciated

I agree, but I think I will try to steal this from Ben, and give you a useful tip that might just do that.
(I’m writing this as I think of a way to solve your problem)

I expect you have read part 9, where you animate the player…?

What you do is just, add those two other animations to the player in the same way, and in the test where the other animations are activated, just add one for falling(you could use the speed the player falls to trigger), and you can use one for landing(downBumping after falling).

That last one might require a Boolean variable or two, to prevent it being interrupted by the other animations.

I suggest you make a Bool for falling, and a Bool for lockDown of animations.

The lockdown will prevent the change of animations.

Lockdown will be activated when falling.

Falling will be activated when player moves down at whatever speed you want it triggered.

fallingAnimation wil activate when falling is true.

landing will animation will activate when DownBumping (test most not be affected by lockdown)

lockdown will end when landing animation is finished.(write code in the last frame on that animation).

I found this guide to be helpful and I learned a lot, but one problem I seemed to face was the collision of walls. I know you already addressed an issue similar to this, but even if I enlarge the character or change the power of the bumps, i still go through walls; especially when jumping or falling. Any advice would be great if you could, thanks!

I’ve run into a problem, after I removed the bouncy floor, the player hits the ground, hesitates, and then sinks through. It’s even tracing, but the character just goes through. If you could help ASAP, that’d be great.

Hey Ben, I’m setting my game up so the camera is fixed in place like an old school Mega Man boss battle. I’ve already swapped out back.x/back.y with player.x/player.y and reversed the + to – and vice versa. I’m having trouble placing my character in a specific position tho. I’ll try to set the player up in the center of the screen, but it keeps spawning in the top left (0,0). Do you know of any way to resolve this issue?
Thanks, Frank

I’m having a problem with the gravity. I input the var gravityConstant and called to it in the loop, but my character does not fall. I moved the character to an object and the character started sinking though the level. I checked my conditionals for the hitPointTest and they work properly, trace with a hit and no trace without a hit.
Even referencing your source code to make sure everything was organized properly, I’m still coming up short as to why gravity is not implemented.

I went ahead and input the jump codes and they work after placing the character on top of a platform.

I’ve noticed that when my character jumps, he drops a little bit into the ground after falling. (i.e. he jumps, then falls. then he jumps and falls a little bit more, then jumps and falls a bit more.) I know that this is because of the gravity constant. When he falls, his y increases by the gravity constant. Then his y is actually below the y of the collision box. This may be incredibly hard to understand based on the way I’m writing it, but I’ve been working on this forever and I can’t fix it. Help would be appreciated. Thanks.

man, your tutorial is amazing and so easy to follow. even when i think i don’t get it, all i have to do is carefully re-read what you said and the code your made and compare that to how i did mine, and hey presto, i found the error. thanks for the help so far :D

I’m trying to do this without the side scrolling. I’ve been fiddling around with the code for ages but my character teleports to the top and very slowly drops down and stops at a grinding holt nowhere near the platform. Also, for some strange reason, it doesn’t seem to be “downBumping” because it wouldn’t trace. I do happen to be using a patchwork of other code but I’m pretty sure it wouldn’t be affecting it. What’s the problem here?

I am wondering how to transition between frames with different animations, depending on button presses and other actions. I’ve tried gotoAndStop inside of functions, but it doesn’t work. Even not after writing stop() at the very beginning.

Do you also know how I can make background images I add not affect my player’s bumpers and just stay as a non-interractive background?

Please help! My character is sinking through the ground, no matter how thick I make it. It seems to stop when I lower the gravityConstant, but then I fall too slowly and it looks silly. I made the dimensions of my character exactly the same as yours, but it still didn’t work. This tut has gone really well so far, but I can’t continue until I can fix this :(

Hey, I was seriously struggling with a sidescrolling project until I found these, so thank you so much for taking time to make these!
I have a question concerning my background scrolling. My player is moving faster than the background scrolls and eventually leaves the screen, never to return. After manipulating variables, I am having troubles getting the background and player speed to match. Off the top of your head, any ideas how I might fix that?

Hello! and thank you very much for these tutorials. Very good and well presented. Im quite new to AS3 and been following your tutorials and I’m telling you, from having no idea to creating something that at least behaves like an platformed its been a great accomplishment for me. I have a question on regards to the jumping code. Instead of using the key functions Im using icons on screen to move my character, but in this code when I press my right icon and then press my b button, the character doesn’t jump. If I press each one individually he walks fine or jumps, but if I press both at the same time it doesn’t jump forward at all? Any ideas? Thanks.

I fixed my problem. I had to use touch events instead as theres only one mouse in the computer it only registers one event. Now the only problem I’m having is the multi-results in the Y after landing. It doesn’t always land in the exact position it always lands in different positions. is not for a lot of difference but is fluctuate between 10 to 30 pixels at the time.

I still haven’t figured why does the main character jumps and lands in different Y coordinates instead of stopping at the top of the collision platform. Any help will be appreciated. Thanks :) Great tutorials!