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.

Note Note: This tutorial is geared towards users who already have some knowledge of platformer physics. If a simpler tutorial is desired, How to Make a Basic Platformer can be used instead.

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
change [speed y v] by [-1] //this can be -0.5 if you wish to have low gravity
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, 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 //this is so you can't fly up
set [speed y v] to [15] //can be any value, test different numbers

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
change [speed y v] by [-1]
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