# How to do simple physics

Games often need simple Newtonian physics to make things move in a believable manner. That basically means, objects have inertia and tend to stay in motion once they're in motion, affected by forces like gravity. Examples include the ship and rocks in Asteroids, the projectiles in any artillery game, and even the characters in a platformer.

Fortunately, simple physics are easy to do! The key concept is: in addition to the object's position, you must also keep track of its velocity. This is normally done by adding two new properties, `vx` and `vy`, to your object.

• vx is the object's horizontal velocity: how much its x position changes per second.
• vy is the object's vertical velocity: how much its y position changes per second.

If we were updating the position of our object once per second, we could just add `vx` to its `x` position, and `vy` to its `y` position. But usually we're updating the screen much faster than that (typically 60 frames per second). The time step (usually called `dt`) is much smaller than 1 second, so the object won't move as far on each step. We accomplish this by simply multiplying `vx` and `vy` by `dt`, before adding them to `x` and `y`.

## Example

The code below loads a sprite in the center of the screen, initially stationary. Then it falls due to gravity, until it hits the bottom of the screen.

```clear
gravity = 100  // acceleration, in pixels/sec^2

obj = new Sprite
display(4).sprites.push obj
obj.x = 480
obj.y = 320
obj.vx = 0
obj.vy = 0

obj.update = function(dt=0.016)
// update velocity (applying gravity)
self.vy = self.vy - gravity * dt

// update position (applying velocity)
self.x = self.x + self.vx * dt
self.y = self.y + self.vy * dt

// apply any limits, collision checks, etc.
if self.y < 32 then
self.y = 32
self.vy = 0
self.vx = floor(self.vx / 2)
end if
end function

while true  // press control-C to exit
obj.update
yield
end while
```

Things to try:

1. Change the initial values of `vx` and `vy` to something other than zero. What happens?
2. When `self.y < 32` (the object hits the ground), instead of setting `self.vy` to zero, what if you set it to `abs(self.vy)` (i.e. make it positive)?
3. Try adding a thruster you can control, by adding this to the "update velocity" section: `if key.pressed("space") then self.vy = self.vy + 500*dt`

For another example, see the flappyBat demo in /sys/demo/.