The Box2D library uses its own special representation of physical objects to achieve the simulation of physics. It's often desirable that some objects are fixed in place and other objects move after physical interaction.
This recipe will show you how to prepare physical objects with the LuaBox2D library in an environment of the Lua language.
First of all, you'll need to set up the world environment where all the physical objects will reside. To do this, you'll have to create a World
object, as shown in the following sample code:
local gravity = Vec2(0, -10) local world = box2d.World(gravity)
You'll often need to have only one World
object. The World
object constructor accepts one Vec2
vector object to set the gravity
vector. You can change it later with the following code:
world.gravity = Vec2(0, -5) -- uses unit m/s^2
Do note that the Box2D library uses metric units. The vector for gravitational acceleration uses m*s-2. However, you can change the overall scale of all the units to suit your game.
From this point, you've got the World
object ready and you can create bodies of physical objects.
The Box2D library was designed with efficiency in mind. Therefore, initial body properties are defined in the BodyDef
object that acts as a template for body objects. The BodyDef
object contains initial properties of the body object such as the body type, position, angle, and damping. Box2D assumes that all objects are static by default. If you want the physical object to be dynamic, you'll have to set this property in the BodyDef
object. The following lines show how to create a static object from the BodyDef
definition:
local body_def = box2d.BodyDef()
body_def.type = 'static'
body_def.position = Vec(0,0)
-- angle uses radian units
body_def.angle = 0
local body = world.createBody(body_def)
This will create a body of physical objects. However, this object doesn't have a shape or size. To fix this, you'll need to create a fixture:
-- definition of crate box object local crate_box = { width = 50, height = 50, density = 1, } local box_shape = box2d.PolygonShape() box_shape.setAsBox( crate_box.width/box2dScalingFactor, crate_box.height/box2dScalingFactor) local box_fixture = body.createFixture(box_shape, crate_box. density)
Now you have created a static box object that can act as a wall because no matter what you'll do, this box will stay in its place.
In contrast to static objects, dynamic objects can move and they are affected by forces. Creating a dynamic object is not much different from creating static ones. The following code shows you how to do it:
local body_def = box2d.BodyDef()
body_def.type = 'dynamic'
body_def.position = Vec(0,20)
-- angle uses radian units
body_def.angle = 0
local body = world.createBody(body_def)
-- definition of crate box object
local crate_box = {
width = 50,
height = 50,
density = 1,
friction = 0.1,
}
local box_shape = box2d.PolygonShape()
box_shape.setAsBox(
crate_box.width/box2dScalingFactor,
crate_box.height/box2dScalingFactor)
-- fixture definition
local fixture_def = box2d.FixtureDef()
fixture_def.shape = box_shape
fixture_def.density = crate_box.density
fixture_def.friction = crate_box.friction
local box_fixture = body.createFixture(fixture_def)
You can see that instead of using the shape and density as a parameter in the createFixture
function, you can use the FixtureDef
object as well. This way you can set all the important fixture parameters in a fixture definition object and reuse this definition later.
Each physical object consists of a body and its fixture. The body of the object contains the position of the object's origin point, angle, damping values, and many other parameters. On the other hand, a fixture defines the physical properties of an object and its shape.
This library divides the physical object types into two main categories: static and dynamic objects. However, there's a third kind of objects called kinematic. Kinematic objects behave as if they have an indefinite mass and they don't respond to forces.
The body object can contain more fixtures to achieve more complex object shapes. To create a new one, simply call the createFixture
function. The Box2D library knows three more shapes you can use: CircleShape
, EdgeShape
, and ChainShape
.
CircleShape
represents a circle with a radius and a position of central point. EdgeShape
can be used to define a line segment with two points. This one is often used on simple platforms but it's not that great on terrain. ChainShape
can be used to create variously shaped terrains. You can see these shapes in the following code:
local circle_shape = box2d.CircleShape() circle_shape.radius = 1 -- central point circle_shape.m_p = Vec2(0,0) local edge_shape = box2d.EdgeShape() edge_shape.vertex1 = Vec2(-1, 0) edge_shape.vertex2 = Vec2(1, 0) local chain_shape = box2d.ChainShape() chain_shape.createChain({ Vec2(-1,0), Vec2(1,1), Vec2(2,1), Vec2(4, 0) })
The body object can contain more than one fixture. You can cycle over the body object fixtures using the following code:
local current_fixture = body.fixture while current_fixture do -- do something with Fixture object current_fixture = current_fixture.next end
3.147.74.211