module Eagle::Physics2D

Overview

2D rigid-body physics in pure Crystal: circles and convex polygons, stacking, friction, restitution, sensors, raycasts and kinematic character movement.

Most games use it through the physics nodes (RigidBody2D, StaticBody2D, KinematicBody2D, Area2D, RayCast2D), which share the global Physics2D.world. The engine steps that world at the fixed rate before physics_process runs.

You can also use a World directly, without nodes, for simulations and tests:

world = Physics2D::World.new
world.gravity = v2(0, 600)
ground = world.add(Physics2D::BodyType::Static, v2(400, 580), Physics2D::Polygon.box(800, 40))
ball = world.add(Physics2D::BodyType::Dynamic, v2(400, 0), Physics2D::Circle.new(16))
60.times { world.step(1_f32 / 60) }
ball.position # resting on the ground

if hit = world.raycast(v2(0, 300), v2(1, 0), max_distance: 800)
  hit.point
end

Units are pixels and seconds, and gravity defaults to 980 px/s² downward.

Defined in:

eagle/physics/body2d.cr
eagle/physics/collision2d.cr
eagle/physics/physics2d.cr
eagle/physics/shapes2d.cr
eagle/physics/world2d.cr

Class Method Summary

Class Method Detail

def self.active? : Bool #

True when the shared world has bodies. The engine skips stepping an empty world.


def self.debug_draw(g : Graphics, color : Color = Color.new(0, 1, 0, 0.6)) : Nil #

Draws the outline of every body in the shared world. Call it from App#draw while tuning collisions.


def self.reset : Nil #

Replaces the shared world with an empty one.


def self.world : World #

The shared world used by the physics nodes.


def self.world=(w : World) #

Replaces the shared world.