This article is about advanced platformer physics. For a basic platformer tutorial, see How to Make a Basic Platformer. For scrolling platformers, see Scrolling Platformer Tutorial.

A platformer is a type of game distinguished by jumping across platforms and avoiding obstacles. In order to make the game realistic, more advanced scripting must be used.

## Gravity

Main article: Simulating Gravity

The most basic gravity script works like this:

```if <touching (ground v)?> then
change y by (10)
else
change y by (-10)
end
```

However, this causes the player to move at a fixed speed and jitter when it touches the ground.

A more realistic gravity script as follows:

```set [speed y v] to [0]
forever
if <(speed y) > [-7]> then // change this amount to have faster or slower terminal velocity
change [speed y v] by [-1] // change this amount to have stronger or weaker gravity
end
change y by (speed y)
check ground touch //this pulls the player out of the ground

define check ground touch
//make sure "run without screen refresh" is enabled
repeat until <not<touching (ground v)?>>
change y by (1)
end
```

This allows the sprite to fall faster and faster, up to a certain terminal velocity, like in real life.

### Jumping

Main article: Jumping

Jumping is as easy as this:

```if <key (space v) pressed?> then
if <not<touching (ground v)?>> then // prevents the player from flying by holding space
set [speed y v] to [15] // this value controls jump height
```

### Ceiling Detection

Let's add to our "check ground touch" block:

```define check ground touch
if <(speed y) < [0] > then
repeat until <not<touching (ground v)?>>
change y by (1)
end
else
set [speed y v] to [0]
end```

That way, if the player is going up and hit a platform, the scripts don't push it through the platform, and instead it stops going up and falls back down.

So the final scripts are:

```when gf clicked
forever
if <(speed y) < [-7]> then
change [speed y v] by [-1]
end
change y by (speed y)
check ground touch
if <key (space v) pressed?> then
if <not<touching (ground v)?>> then
set [speed y v] to [15]
end
end
if <key (left v) pressed?> then //the moving script
change x by (-4)
end
if <key (right v) pressed?> then //ditto
change x by (4)
end

define check ground touch
if <(speed y) < [0] > then
repeat until <not<touching (ground v)?>>
change y by (1)
end
else
set [speed y v] to [0]
end
```

## Wall Detection

The "check ground touch" block causes the player to walk up walls. To get rid of this, make a new custom block called move:

```define move (distance :: custom)
//this is also "run without screen refresh"
change x by (distance :: custom)
set [slope v] to [0] //new variable
repeat until <<(slope) > [8]> or <not <touching [ground v]>>>
change y by (1)
change [slope v] by [1]
end
if <(slope) > [8]> then
change x by ((0)-(distance :: custom)
change y by ((0)-(slope)
end
```

Every time the player moves left or right, it checks if the slope is higher than 8 (basically, if it moves you more than 8 units), if it is, it moves you back. Replace the "change x by ()" blocks with two of these.

## Hitboxes

Main article: Hitbox

If your player, avatar, etc. has arms, they will catch on the platforms (if your player is a smooth rectangle you can skip this). The answer to that is a hitbox. Create a new costume for your sprite and make it a filled rectangle about the size of your normal costume (the one it's showing). Then update your scripts like this:

```when gf clicked
forever
switch costume to [hitbox v]
... //other scripts
switch costume to [regular v]
end```

## Walking Momentum

To simulate momentum, it needs a gliding effect - after you stop pressing the left/right key, it "glides" to a stop instead of stopping right away. First, update the "move" block - replace the "change x" block with a "change speed x" block

```define move (dist)
change [speed x v] by (dist) //replace with this
... //the other scripts```

Then, after the "check ground touch" block, add:

```when gf clicked
forever
switch costume to [hitbox v]
change [speed y v] by [-1]
change y by (speed y)
check ground touch::custom
set [speed x v] to ((speed x)*(0.8)) //add this!
change x by (speed x) //and this!
...
end```

What this does is slowly (but not too slowly) speed up when you are pressing the key, and slowly lose speed when you let go.

## See Also

Cookies help us deliver our services. By using our services, you agree to our use of cookies.