Skip to main content

How to: Movement

There are two main ways to move a body around the world, we will call them walking and flying. Walking involves taking one step at a time. The velocity only lasts for one tick, and then it is reset to zero. Flying involves gaining velocity that continues to affect the body until it is changed by another force or by friction.

Flying

Flying is the most straightforward way to move a body around the world. Simply modify the Velocity property of the body directly to make it fly in a certain direction.

Subspawn ship {
use body=ship, radius=1, shape=Equilateral(numPoints=3)

Body(pos=20*RandomVector)
PolygonCollider(category=Category:Ship)
PolygonSprite(color=#0f0)

on BeforePhysics {
// Accelerate to wards the pointer
Velocity += 0.1 * (Pointer - Pos).Direction
}
}
tip

BeforePhysics occurs just before the physics simulation step of each tick, which means that any changes to velocity made in this block will be taken into account during this tick's physics simulation. It is a good idea to use BeforePhysics any time you want to affect a body's motion.

Walking

Let's say you have a character that you want to take a step forward. One way to achieve this is to simply give it a new Pos, a short distance in front of its current position. However, if you do that, the character will just teleport to the new position, sometimes tunnelling into walls or other characters in the process, which can cause unrealistic collisions that involve being ejected out of walls at high speeds.

Call the ForcefulStep to move the body to another position by applying a one-off force during the next physics simulation. Similarly, call ForcefulTurn to change the body's heading by applying a one-off torque during the next physics simulation.

If, in the process of taking the step, the body collides with another body, and the collision will be simulated in a realistic manner. This might mean the body bounces back, or it might push the other body out of the way.

Subspawn hero {
use body=hero, radius=1, shape=Circle

Body(pos=20*RandomVector)
PolygonCollider(category=Category:Hero)
PolygonSprite(color=#0f0)

on ButtonDown(ArrowRight) {
behavior<walk> on BeforePhysics {
// Take on step to the right
ForcefulStep(@(10, 0))
}
}
on ButtonDown(ArrowRight) {
delete behavior<walk>
}
}

This technique makes a body realistically push other bodies when it is walking into them, for example a hero pushing into a boulder or into another hero.

tip

When a body using ForcefulStep walks into a wall, they will bounce off. If you do not like this, try setting restitution=0 for ForcefulStep, e.g. ForcefulStep(@(10, 0), restitution=0).