Creating static and dynamic objects

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.

Getting ready

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.

How to do it…

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.

How it works…

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.

There's more…

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
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.9.169