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.

Search Document