physics
physics
¶
2D rigid-body physics on Box2D.
Build a World with some gravity, add static, dynamic or kinematic bodies,
give them box or circle shapes, then call update each frame to step the
simulation. Read a body's position and angle to draw it.
Box2D is happiest in small units like meters, so pick a scale (say 50 pixels per unit), simulate in those units, and multiply when you draw, rather than feeding pixel-sized numbers to the solver.
This needs Box2D installed (brew install box2d) and is imported on its own
with import nim2d/physics, since not every program wants the dependency.
BodyType
¶
type BodyType = enum
Static bodies never move (floors, walls), dynamic ones move and collide,
kinematic ones move only by the velocity you set.
Values
-
btStatic -
btDynamic -
btKinematic
World
¶
type World = ref object
A physics world holding bodies and joints, stepped with update.
Body
¶
type Body = object
One rigid body in a world. Give it shapes with addBox and addCircle,
and read it back with position, angle and velocity.
newWorld ¶
proc newWorld(gravityX = 0.0; gravityY = 9.81): World
A physics world with the given gravity. Positive y points down, matching the
screen, so the default pulls bodies downward.
Parameters
-
gravityX(auto) -
gravityY(auto)
Returns
World
destroy ¶
proc destroy(w: World)
update ¶
proc update(w: World; dt: float; subSteps = 4)
Advance the simulation by dt seconds. A steady dt and a few sub-steps
give the most stable result.
Parameters
-
w(World) -
dt(float) -
subSteps(auto)
newBody ¶
proc newBody(w: World; x, y: float; kind = btDynamic): Body
Add a body at (x, y). Dynamic bodies move and collide, static ones never
move (floors and walls), kinematic ones move only by the velocity you set.
Parameters
-
w(World) -
x(float) -
y(float) -
kind(auto)
Returns
Body
addBox ¶
proc addBox(b: Body; halfWidth, halfHeight: float; density = 1.0; friction = 0.6; restitution = 0.0)
Give the body a rectangular shape, sized by its half extents.
Parameters
-
b(Body) -
halfWidth(float) -
halfHeight(float) -
density(auto) -
friction(auto) -
restitution(auto)
addCircle ¶
proc addCircle(b: Body; radius: float; density = 1.0; friction = 0.6; restitution = 0.0)
Give the body a circular shape.
Parameters
-
b(Body) -
radius(float) -
density(auto) -
friction(auto) -
restitution(auto)
position ¶
proc position(b: Body): tuple[x, y: float]
The body's center position.
Parameters
-
b(Body)
Returns
tuple[x, y: float]
angle ¶
proc angle(b: Body): float
velocity ¶
proc velocity(b: Body): tuple[x, y: float]
The body's linear velocity.
Parameters
-
b(Body)
Returns
tuple[x, y: float]
setVelocity ¶
proc setVelocity(b: Body; x, y: float)
Set the body's linear velocity.
Parameters
-
b(Body) -
x(float) -
y(float)
applyForce ¶
proc applyForce(b: Body; x, y: float)
Apply a steady force at the body's center.
Parameters
-
b(Body) -
x(float) -
y(float)
applyImpulse ¶
proc applyImpulse(b: Body; x, y: float)
Apply an instantaneous impulse at the body's center, for a kick or a jump.
Parameters
-
b(Body) -
x(float) -
y(float)
setPosition ¶
proc setPosition(b: Body; x, y: float; angle = 0.0)
Teleport the body to a position and angle.
Parameters
-
b(Body) -
x(float) -
y(float) -
angle(auto)
destroy ¶
proc destroy(b: Body)
userData ¶
proc userData(b: Body; value: int)
Tag a body with an integer of your own, handy for telling bodies apart in
raycasts, queries and contact events.
Parameters
-
b(Body) -
value(int)
userData ¶
proc userData(b: Body): int
The integer set with userData=, or 0 if none was set.
Parameters
-
b(Body)
Returns
int
Joint
¶
type Joint = object
A constraint tying two bodies together, made by the joint constructors on
a world.
destroy ¶
proc destroy(j: Joint)
revoluteJoint ¶
proc revoluteJoint(w: World; a, b: Body; x, y: float; enableMotor = false; motorSpeed = 0.0; maxMotorTorque = 0.0; enableLimit = false; lowerAngle = 0.0; upperAngle = 0.0): Joint
A hinge pinning two bodies at the world point (x, y), with an optional motor
and angle limits.
Parameters
-
w(World) -
a(Body) -
b(Body) -
x(float) -
y(float) -
enableMotor(auto) -
motorSpeed(auto) -
maxMotorTorque(auto) -
enableLimit(auto) -
lowerAngle(auto) -
upperAngle(auto)
Returns
Joint
distanceJoint ¶
proc distanceJoint(w: World; a, b: Body; x1, y1, x2, y2: float; enableSpring = false; hertz = 0.0; dampingRatio = 0.0): Joint
A rod or spring holding two world anchor points a fixed distance apart. With
a spring it stretches; without one it stays rigid.
Parameters
-
w(World) -
a(Body) -
b(Body) -
x1(float) -
y1(float) -
x2(float) -
y2(float) -
enableSpring(auto) -
hertz(auto) -
dampingRatio(auto)
Returns
Joint
prismaticJoint ¶
proc prismaticJoint(w: World; a, b: Body; x, y, axisX, axisY: float; enableMotor = false; motorSpeed = 0.0; maxMotorForce = 0.0; enableLimit = false; lowerTranslation = 0.0; upperTranslation = 0.0): Joint
A slider letting two bodies move only along the axis (axisX, axisY), with an
optional motor and travel limits.
Parameters
-
w(World) -
a(Body) -
b(Body) -
x(float) -
y(float) -
axisX(float) -
axisY(float) -
enableMotor(auto) -
motorSpeed(auto) -
maxMotorForce(auto) -
enableLimit(auto) -
lowerTranslation(auto) -
upperTranslation(auto)
Returns
Joint
weldJoint ¶
proc weldJoint(w: World; a, b: Body; x, y: float): Joint
Welds two bodies rigidly together at the world point (x, y).
Parameters
-
w(World) -
a(Body) -
b(Body) -
x(float) -
y(float)
Returns
Joint
wheelJoint ¶
proc wheelJoint(w: World; a, b: Body; x, y, axisX, axisY: float; enableMotor = false; motorSpeed = 0.0; maxMotorTorque = 0.0): Joint
A wheel: a suspension spring along the axis plus a spinning motor, for cars.
Parameters
-
w(World) -
a(Body) -
b(Body) -
x(float) -
y(float) -
axisX(float) -
axisY(float) -
enableMotor(auto) -
motorSpeed(auto) -
maxMotorTorque(auto)
Returns
Joint
motorJoint ¶
proc motorJoint(w: World; a, b: Body; offsetX, offsetY, maxForce, maxTorque: float): Joint
Drives one body to a position and angle offset from another, like a top-down
character controller pushed around without fighting the solver.
Parameters
-
w(World) -
a(Body) -
b(Body) -
offsetX(float) -
offsetY(float) -
maxForce(float) -
maxTorque(float)
Returns
Joint
angle ¶
proc angle(j: Joint): float
The current angle of a revolute joint.
Parameters
-
j(Joint)
Returns
float
translation ¶
proc translation(j: Joint): float
The current translation of a prismatic joint.
Parameters
-
j(Joint)
Returns
float
setMotorSpeed ¶
proc setMotorSpeed(j: Joint; speed: float)
Drive a revolute joint's motor at speed. Enable the motor when you create
the joint with enableMotor = true.
Parameters
-
j(Joint) -
speed(float)
RayHit
¶
type RayHit = object
Fields
-
hitbool– whether the ray struck anything -
bodyBody– the body it struck (only when `hit`) -
xfloat– the point of impact -
yfloat– the point of impact -
nxfloat– the surface normal there -
nyfloat– the surface normal there -
fractionfloat– how far along the ray, 0 at the start, 1 at the end
raycast ¶
proc raycast(w: World; x1, y1, x2, y2: float): RayHit
Cast a ray from (x1, y1) to (x2, y2) and return the closest body it hits.
Parameters
-
w(World) -
x1(float) -
y1(float) -
x2(float) -
y2(float)
Returns
RayHit
queryBox ¶
proc queryBox(w: World; x, y, width, height: float): seq[Body]
Every body whose shapes overlap the box (x, y, width, height).
Parameters
-
w(World) -
x(float) -
y(float) -
width(float) -
height(float)
Returns
seq[Body]
Contact
¶
type Contact = object
A pair of bodies that started or stopped touching during a step.
Fields
-
aBody -
bBody
beginContacts ¶
proc beginContacts(w: World): seq[Contact]
Pairs of bodies that started touching during the last update. Compare their
userData to tell which is which.
Parameters
-
w(World)
Returns
seq[Contact]
endContacts ¶
proc endContacts(w: World): seq[Contact]
Pairs of bodies that stopped touching during the last update.
Parameters
-
w(World)
Returns
seq[Contact]