kitten/simulate
This module contains functions for working with the physics system. Please remember that the engine cannot simply run the physics for you, and that you will need to write game logic specific to your game. Think of this module as a collection of helper functions and not a full physics engine.
The functions in this module may be changed in the near future.
Functions
pub fn apply_forces(
vel vel: Vec2,
mass mass: Float,
forces forces: List(Vec2),
) -> Vec2
Adjusts the given velocity by applying a list of forces and taking the mass and delta_time
into account.
Returns only the new velocity.
pub fn apply_friction(vel vel: Vec2, f f: Float) -> Vec2
Adjusts the given velocity by reducing all of its components, taking delta_time
into account. f
must be non-negative, or the function will fail at runtime.
pub fn apply_gravity(
vel vel: Vec2,
mass mass: Float,
g g: Float,
) -> Vec2
Adjusts the given velocity by reducing its vertical component, taking delta_time
into account.
pub fn collision(
obj1 obj1: #(Vec2, Vec2, Vec2, Float),
obj2 obj2: #(Vec2, Vec2, Vec2, Float),
e e: Float,
f f: Float,
) -> #(#(Vec2, Vec2), #(Vec2, Vec2))
Resolves the collision between two rectangular objects, defined by (in order) their centre positions,
sizes, velocities and masses; taking into account the elasticity and friction coefficients. Note that this
funcion only changes the velocities of the objects and adjusts their positions to prevent an overlap, but
does not apply any motion. Use the move
function to do the latter.
Set the mass to 0.0 to simulate an object as static.
pub fn collisions(
objects objects: List(#(Vec2, Vec2, Vec2, Float)),
e e: Float,
f f: Float,
) -> List(#(Vec2, Vec2))
Resolves collisions between every pair of objects in the list, defined by (in order) their centre
position, size, velocity and mass; taking into account the elasticity and friction coefficients.
Note that this funcion only changes the velocities of the objects and adjusts their positions to
prevent an overlap, but does not apply any motion. Use the move
function to do the latter.
Set the mass to 0.0 to simulate an object as static.
pub fn delta_time() -> Float
Returns the amount of time since the previous frame was rendered, scaled so that when running
at 60 fps, this value should always be approximately 1.0
.
pub fn is_intersecting(
point1 point1: Vec2,
point2 point2: Vec2,
pos pos: Vec2,
size size: Vec2,
) -> Bool
Checks if the line segment connecting the two points intersects a rectangle, defined by its centre position and size. Uses a slightly unoptimised Liang-Barsky algorithm.
Example:
is_intersecting(Vec2(0.0, -100.0), Vec2(0.0, 100.0), Vec2(0.0, 0.0), Vec2(100.0, 100.0))
// -> True
is_intersecting(Vec2(-100.0, -100.0), Vec2(-100.0, 100.0), Vec2(0.0, 0.0), Vec2(100.0, 100.0))
// -> False
pub fn is_overlapping(
pos1 pos1: Vec2,
size1 size1: Vec2,
pos2 pos2: Vec2,
size2 size2: Vec2,
) -> Bool
Checks if the two rectangles, defined by their centres and sizes, are overlapping. Sharing an edge or a corner but no inner space counts as an overlap.
Examples:
simulate.is_overlapping(Vec2(0.0, 0.0), Vec2(10.0, 10.0), Vec2(5.0, 5.0), Vec2(10.0, 10.0))
// -> True
simulate.is_overlapping(Vec2(0.0, 0.0), Vec2(10.0, 10.0), Vec2(50.0, 50.0), Vec2(10.0, 10.0))
// -> False
pub fn is_within(
point point: Vec2,
pos pos: Vec2,
size size: Vec2,
) -> Bool
Checks if a point lies within the rectangle, defined by its centre and size. If the point lies on the edge of the rectangle, it is considered to be within it.
Examples:
simulate.is_within(Vec2(0.0, 0.0), Vec2(0.0, 0.0), Vec2(10.0, 10.0))
// -> True
simulate.is_within(Vec2(0.0, 0.0), Vec2(50.0, 50.0), Vec2(10.0, 10.0))
// -> False
pub fn move(pos pos: Vec2, vel vel: Vec2) -> Vec2
Adjusts the position of an object by adding its velocity to it. Returns only the new position.
A simple alias for vec2.add
that takes delta_time
into account.
Example:
simulate.move(Vec2(0.0, 5.0), Vec2(10.0, 0.0))
// -> Vec2(10.0, 5.0) (approx.)
pub fn screen_to_world(pos: Vec2) -> Vec2
Converts the given position in screen coordinates to its equivalent in
world coordinates, under the transformation specified in the view
function in the previous frame.
Screen coordinates start in the top-left corner of the canvas, with the x-axis pointing right and the y-axis pointing down, and have the same unit as world coordinates.
See the draw
module for camera-related functions that specify this
transformation.
pub fn world_to_screen(pos: Vec2) -> Vec2
Converts the given position in world coordinates to its equivalent in
screen coordinates, under the transformation specified in the view
function in the previous frame.
Screen coordinates start in the top-left corner of the canvas, with the x-axis pointing right and the y-axis pointing down, and have the same unit as world coordinates.
See the draw
module for camera-related functions that specify this
transformation.