Gravity

It seems like quite a few people are having a little difficulty with Gravity in their games, especially their platform games, they either don't know how to make their player "fall downwards" or they find that their player is "eating through the floor" every time they are moving.  This brief tutorial will (hopefully) go someway to explaining how to use gravity and to overcome the pitfalls it can create.

 

Falling Down

What you should know about (real world) gravity is that it is constantly pulling you down (actually towards the centre of the Earth), every single millisecond of every single day you are constantly being pulled downwards, if you translate this to your game you should then realise where the gravity 'code' should be placed: the Step Event of the character to fall as the Step Event is called constantly throughout your game. Every single step of the way we need to check if the player is standing on something, if so, we want to switch the gravity 'off' as it were, let's take this one step at a time:

 

DRAG & DROP

gravityactions

 

If a position is collision free

Ok, we need to check whether the position beneath his feet is solid (so he's feet are actually touching something solid).  Go to the control tab and drag over if a position is collision free, leave the 'x' as 0 as we don't want to check on the horizontal plain (left or right).  In the 'y' place a 1, this means were looking 1 pixel below the character.

 

The pixel co ordinates of the screen start at the top-left as (0,0) [x = 0 and y = 0] so one pixel to the right would be (1,0) [x = 1 and y = 0] and one pixel down and one pixel to the right would be (1,1) [x = 1 and y = 1] and so placing a 1 in the 'y' would look 1 pixel below.

 

Make sure you have the Relative box ticked to indicate you're looking 1 pixel below the character (where ever he is), otherwise your game will think you're checking 1 pixel below the top-left of the screen! (0,1)

 

In the Objects, select Only solid to select solid objects.  (Make sure any platforms you create have Solid ticked.)

 

Set the gravity

If the position is indeed collision free we need to have gravity take effect and pull the character down.

 

From the move tab drag over the set the gravity icon.  The direction we need is downwards, this translates to 270.   The directions are set out in a counter-clockwise format, as follows:

 

0 = right : 90 = up : 180 = left : 270 = down

 

direction

 

You can use other values to have your character move in a finer angled direction if need be.

 

The gravity depends on how fast you want your character to fall; this value should be played around with to see what suits you best.

 

Else

If the player is on something solid, do the following instead:

 

Set the gravity

We now need to stop the gravity taking effect, basically, it's a copy of the previous gravity settings except this time the gravity is 0 (hence no gravity).

 

Set the vertical speed

Even though we've turned off gravity as it were, we still need to stop the character falling, we need to reduce he's vertical speed to 0 otherwise he'd continue falling even when he's walking on platforms, this is where the dreaded eating through the floor problem comes in.

 

If you want to use GML instead of Drag & Drop, here's the code; change to suit:

 

if place_free(x,y+1) //Check if player is touching a solid

{

gravity = 1; // Set gravity, change to suit

}

else

{

gravity = 0; // Stop the gravity

vspeed = 0;

}

 

--oOo--

 

Jumping

That's all very well for something that doesn't need to go up, like a rolling rock for example, but what if we want the player to jump? Because you're setting the Vertical Speed to 0 every step, the player doesn't get chance to jump as he's vertical speed is set to 0 immediately, so this needs to be changed. The first thing to do is remove the Set the vertical speed from the bottom of the player's Step Event. The next thing we need to do is create a Collision Event for the player, between the player and the platform he's going to walk on.

 

collisionstopvertspeed

 

In the above, the actions will take place (he'll stop falling) when he collides with a block called obj_collblock-1.

 

Move to contact in direction direction

Opening this action, you will see 3 variables, direction:, maximum:, against:

 

direction: this can be any number from 0 to 359 (see earlier for more information about direction) but you'll notice here that instead of a number, the word direction is there, this is a Keyword used by Game Maker to indicate the current direction of the object and is used to stop the object from jumping to a different position when it collides, try changing it to a number and see what happens.
maximum: You can specify the maximal distance to move. For example, when the instance is falling you can move a maximal distance down until an object is encountered. The usual is 12.
against: here you can indicate whether you want to react against only those objects you've ticked as solid, or any object that you happen to fall upon.

 

Set vertical speed

And here's where you place the Set vertical speed you removed from the player's Step Event, just set it to 0 so he doesn't fall anymore!

 

Here's the GML version:

 

move_contact_solid(direction,12);

vspeed = 0;

 

The last thing we need to do now is tell the player to actually jump when the jump key is pressed:

 

jumpkey

 

If there is a collision at position

What were doing here is making sure that the player is actually standing on something he can jump off! Otherwise he'd be jumping when the jump key is pressed, no matter where he is, even in the air!

 

x: this should be left at 0 because we're not checking anything on the horizontal plain (either side of him).
y: as we need to check directly beneath the player's feet, this is indicated by a 1 (1 pixel below the character).
Only solid: again, this checks whether to interact with only solid objects or all objects.
Relative: you must make sure this is check as to check one pixel below the player and not the pixel at location (0, 1).

 

Set the vertical speed

This one is opposite from the others in the fact that you want to actually change the vertical speed and not just set it to 0. Because you want the player to jump up the screen, you must place a minus number here (just think of it as minus numbers jump upwards), the bigger the minus number, the higher the jump, try around -7 and work from there.

 

And again, here's the GML equivalent:

 

// Check whether under the player is not solid (notice the ! before place_free)

if !place_free(x,y+1)

{

vspeed = -7

}

 

Revision #2