Box2D Extension for Defold
Defold already has Box2D as a physics engine, however it's very limited. Therefore to unleash its full potential this extension was made. It doesn't cover the full Box2D API yet, but it's easy to add particular features you are missing. PRs are welcome.
In this extension Box2D is not tied to the Defold world so to speak, it can run fully independent. This for instance allows you to run a quick simulation of a flying projectile when a player is aiming and show the computed projectile path. Yes, like in Angry Birds.
You can have as many physics worlds as you want and it's up to you how you would like to tie physics objects and graphical objects on screen together. Normally you would just set your game object position and rotation in the update method to its physics body's position and rotation.
Keep in mind that Box2D works in meters, not in pixels. Either scale each physics value to match your game coordinate system, or scale down your game world to match the physics coordinate system. Some games are better coded with the first option, others with another.
API Overview
Functions
Properties
box2d.dynamic_body
box2d.static_body
box2d.kinematic_body
box2d.distance_joint
box2d.friction_joint
box2d.gear_joint
box2d.motor_joint
box2d.mouse_joint
box2d.prismatic_joint
box2d.pulley_joint
box2d.revolute_joint
box2d.rope_joint
box2d.weld_joint
box2d.wheel_joint
Events
Project Settings
Open game.project
and a new entry to the dependencies
property:
https://github.com/Lerg/extension-box2d/archive/master.zip
Then select Project -> Fetch Libraries
to download the extension in your project.
After that you have to disable Defold's physics engine otherwise the inner libraries would clash and your game won't build. To do so you can open game.project
and set App Manifest
to /box2d/physics_null.appmanifest
.
Functions
box2d.init()
Initializes the extension and displays Box2D version.
box2d.new_world(params)
Crates and returns a new physics world.
The params
table
gravity optional
Vector3. Sets the gravity vector for the world. Default is (0, -10).
Example
box2d.init()
local world = box2d.new_world{
gravity = vmath.vector3(0, -20, 0)
}
Box2D world API.
Functions
world.new_body(params)
Creates a new physics body. Please refer to the official Box2D documentation for body descriptions and their parameters.
The params
table
type optional
Body type. box2d.static_body
, box2d.dynamic_body
(default) or box2d.kinematic_body
.
is_fixed_rotation optional
Boolean.
position optional
Vector3.
is_sensor optional
Boolean.
density optional
Float.
friction optional
Float.
restitution optional
Float. Bouncyness.
width optional
Float. If width and height are set a box is created.
height optional
Float.
radius optional
Float. If radius is set and width/height are missing a circle is created.
on_enter_collision optional
Function. Receives collision event.
on_exit_collision optional
Function. Receives collision event.
on_before_collision optional
Function. Receives collision event.
on_after_collision optional
Function. Receives collision event.
Example
self.world = box2d.new_world{
gravity = self.gravity
}
local ground_body = self.world:new_body{
type = box2d.static_body,
position = vmath.vector(0, -500),
width = 1000,
height = 10,
friction = 1,
on_enter_collision = function(event)
print('event.other.position', event.other.position)
end
}
world.new_joint(params)
Creates a new joint between physics bodies. Please refer to the official Box2D documentation for joint descriptions and their parameters.
The params
table
type optional
Joint type.
collide_connected optional
Boolean.
length optional
Float.
frequency optional
Float.
damping optional
Float.
max_force optional
Float.
max_torque optional
Float.
angular_offset optional
Float.
ratio optional
Float.
correction_factor optional
Float.
body optional
Physics body.
other_body optional
Physics body.
joint optional
Physics joint.
other_joint optional
Physics joint.
anchor optional
Vector3.
other_anchor optional
Vector3.
linear_offset optional
Vector3.
target optional
Vector3.
axis optional
Vector3.
Example
local joint = self.world:new_joint{
type = box2d.weld_joint,
body = player_body,
other_body = wall_body,
anchor = player_body.position
}
world.step(time_step, velocity_iterations, position_iterations)
Progresses the simulation.
time_step
Float.
velocity_iterations
Integer.
position_iterations
Integer.
Example
function update(dt)
self.world:step(dt, 6, 4)
end
world.destroy()
Destroys physics world and all physics bodies in it.
Events
collision
Occurs when physics bodies are colliding.
event.self
Physics body.
event.other
Physics body.
Box2D Body API.
Functions
Properties
body.apply_force(force, position)
Applies force to the body.
force
Vector3.
position optional
Vector3.
body.destroy()
Destroys the body.
body.active
Boolean. Read/Write.
body.angular_velocity
Float. Read/Write.
body.position
Vector3. Read/Write.
body.type
Body type. Read/Write.
body.angle
Float. Read.
Usage
Create a world using box2d.new_world()
, add bodies calling world:new_body()
with the newly created world. Run physics simulation calling world:step()
, usually in your update()
method. Play with physics bodies by applying force to them or changing their velocities, update visual representation of physics bodies with position and angle of the bodies.
Patreon
If you like this extension please consider supporting me on Patreon https://patreon.com/Lerg