# Speed and gravity

This page describes how to implement basic physics in sidescroller games (running around, jumping, etc.). This should help you make your game have decent controls and in many cases may be more than enough. You should be able to also apply similar concepts in other situations.

**
Note: this page doesn't talk about collision (that's a whole topic that
deserves a page on its own and depends on the particular game), only
speed physics.
**

## Subpixels

First of all: using pixels for position is a bad idea. Think about it: if the slowest speed you can store is 1px, then that'll be 60px per second (since you add it every frame). You can't do slower than that, and the next step is 120px per second. That's way too much.

Instead we must use a smaller unit (a "subpixel"), or in other words, make it so that 1px is a large number, e.g. 65536 (a power of two). Then if e.g. we want to move 0.75px per frame (45px per second), we could store it as 0.75 × 65536 = 49152. This is called "fixed point".

To show something on screen, we divide the number by a pixel, but we keep the whole number while doing physics. Division on the 68000 is slow, so make sure to use a power of two (then you can use bit shifting, which is much faster!).

#### Iwis says

You may want to look at our page on fixed point to get a better idea of what we're talking about as well as some hints on how to do this in an optimal way.

#### Iwis says

If you're using SGDK, it already comes with fixed point stuff. Look at
the `fix32`

type and relevant functions like
`fix32Add`

(add two `fix32`

values) and
`fix32Int`

(get the integer part out of a `fix32`

).

## X and Y speeds

There are two speed values you should need:

- Horizontal speed (X speed)
- Vertical speed (Y speed)

They should be self-explanatory. The "speed" is pretty much how many pixels an object moves every frame. You should keep track of the speed of every object across frames, so store it as part of their current state.

Every frame, after you've done all speed calculations (what we're going to see after this), you can apply the result by simply adding the speed to the current position:

`x` = `x` + `x_speed`
`y` = `y` + `y_speed`

## Running around

The simple choice to make a character walk or run is to set the
horizontal speed (X speed) to how fast they should move, but that doesn't
feel natural. Instead, you should *accelerate* the speed, i.e. make
the speed increase over a few frames.

Acceleration is simply incrementing speed every frame:

`x_speed` = `x_speed` + `acceleration`

However, you don't want to keep going faster non-stop! You want to impose
a limit on how fast you go (known as the "speed cap"). So if we cross the
speed cap, we prevent the speed from going beyond that. Note that if we
were *already* going faster we do nothing at all (to prevent
awkward situations).

The reason for checking whether acceleration is positive or negative is to cope with the fact that the limit needs to match, nothing more.

**if** `acceleration` == 0
**do** **nothing**
**else** **if** `acceleration` > 0 **and** `x_speed` < `limit`
`x_speed` = `x_speed` + `acceleration`
**if** `x_speed` > `limit` **then** `x_speed` = `limit`
**else** **if** `acceleration` < 0 **and** `x_speed` > -`limit`
`x_speed` = `x_speed` + `acceleration`
**if** `x_speed` < -`limit` **then** `x_speed` = -`limit`
**end**

### Stop running

When we release the left/right button we want to *decelerate*,
i.e. start slowing down. Deceleration is decrementing the speed every
frame. We check that it doesn't cross 0 (since it may not land exactly
on it), but it's otherwise similar to what we did above.

**if** `x_speed` == 0
**do** **nothing**
**else** **if** `x_speed` > 0
`x_speed` = `x_speed` - `deceleration`
**if** `x_speed` < 0 **then** `x_speed` = 0
**else** **if** `x_speed` < 0
`x_speed` = `x_speed` - `deceleration`
**if** `x_speed` > 0 **then** `x_speed` = 0
**end**

### Running into a wall

When moving around you may run into a wall and will need to react to it. Just set horizontal speed to 0 to stop.

## Jump and fall

Besides horizontal speed (X speed), there's also vertical speed (Y speed). Gravity is accelerating the vertical speed every frame (e.g. increase it 0.25px every frame). When you hit the floor, the vertical speed is reset back to 0, so that next time you fall you will start by falling slowly again.

`y_speed` = `y_speed` + `gravity`

Jumping is pretty much setting the vertical speed to a large negative number, e.g. -7px per frame. So, if the jump button is pressed and you're on the floor, change the vertical speed then let gravity do its job (and make sure to make a "boing" noise!).

**if** `jump_button` **and** `on_floor`
`y_speed` = -`jump_speed`
**play_sfx** `jump`
**end**

### Friction while in the air

If something feels off, that's because while you're in the air it should
be harder to change your horizontal speed! To fix this, we can make
*both* acceleration and deceleration to be half as strong while
we're in the air (do this before doing the speed calculations):

**if** **not** `on_floor`
`acceleration` = `acceleration` >> 1
`deceleration` = `deceleration` >> 1
**end**

### Variable jump height

In many genres it's common to be able to jump higher or lower depending
how "hard" (how long) you press the jump button. There are several
approaches to this, I'm going to focus on the *Project MD* approach
since it's simple.

The idea is: if you're moving upwards *and* you aren't holding
down the jump button, then you fall faster. Which means that applying
gravity now should look more like this:

`y_speed` = `y_speed` + `gravity`
**if** `y_speed` < 0 **and** (**not** `jump_button`)
`y_speed` = `y_speed` + `extra_gravity`
**end**

## Useful numbers

Here are some numbers that have served me well from experience, mainly intended for the kind of platformers you normally see on 4th generation consoles. You should tweak these depending on your needs (try them, play, then change anything that feels off).

**Running max speed:**2.5px per frame**Running acceleration:**0.25px per frame**Initial jump speed:**-7px per frame**Usual falling speed:**0.25px per frame**Extra falling speed:**0.25px per frame more

If you're making a game more like Sonic (where the emphasis is on slowly gaining and keeping momentum), then something like this may fit better:

**Running max speed:**5px per frame**Running acceleration:**0.125px per frame