From Test-Scratch-Wiki
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.
![]() | This tutorial is geared towards users who already have intermediate knowledge of Scratch. For those new to Scratch, 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
- 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 are on the moon change y by (speed y) check ground touch //this pulls the player out of the ground define check ground touch //make sure this is "run without screen refresh" 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) //this is also "run without screen refresh" change x by (distance) 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) change y by ((0)-(slope) end
Every time the player 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
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 (distance) change [speed x v] by (distance) //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.