Skip to content

Latest commit

 

History

History

physics

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

Contents

The physics extension is a small wrapper around libGDX' Box2D - thus, it requires having the Box2D dependency in the project. It is currently composed of the following components:

PhysicsUtility

The PhysicsUtility class contains utility conversion methods from Box2D units to pixels and from pixels to Box2D units. By using a pixels-to-meters conversion metric, we can keep thinking in pixels, which is useful. These conversions are done under the hood, meaning that you probably won't need to call any of this class' methods.

PhysicsWorld

The PhysicsWorld encapsulates a Box2D World.

With debugMode set to true (which is the default), you can debug your world with an inner PhysicsDebugger instance (explained below). You will want to have this mode toggled off on a released version of your app, as having the debugger running can be CPU-heavy, especially on mobile devices.

To instantiate a PhysicsWorld, you need to supply the world dimensions:

val world = PhysicsWorld(WORLD_WIDTH, WORLD_HEIGHT)

If you don't explicitly pass a third argument, the PhysicsConfig, then the default one will be used. You can always pass a custom one:

val customConfig = PhysicsConfig(...)
val world = PhysicsWorld(WORLD_WIDTH, WORLD_HEIGHT, customConfig)

PhysicsConfig

The PhysicsConfig class holds a bunch of values that will set the physics environment of some PhysicsWorld. The controllable values (which can't be changed in runtime) are the following:

  • Gravity: Defaults to (0f, -9.8f).
  • Timestep: Default to 1 / 60f.
  • Velocity Iterations: Defaults to 6.
  • Position Iterations: Defaults to 2.

PhysicsDebugger

The PhysicsDebugger is used to debug a given PhysicsWorld, and is a friendly wrapper around Box2DDebugRenderer. This debugger contains a dedicated Camera and Viewport, meaning it can adapt to resize events.

Builders

The BodyBuilder lets you build a customizable Body, with one BodyDef and one or more FixtureDef.

It depends on two other builders: the BodyDefBuilder, that lets you build a customizable BodyDef, and the FixtureDefBuilder, which lets you build one or more customizable FixtureDef.

It's important to note that the constructor of the BodyBuilder takes in a PhysicsWorld - this means that all bodies created within a given instance of BodyBuilder will be hosted in that world. It is possible to change the current world by calling changeWorld, or even dispose it with disposeWorld.

Usage

This is how, in Box2D, we'd generally create a dynamic circle-shaped body, given a position, radius and restitution:

Without the body builder it is rather unpractical and doesn't look too friendly:

val bodyDef = BodyDef().apply {
  type = BodyDef.BodyType.DynamicBody
  position = Vector2(20f, 30f)
}

val circleShape = CircleShape().apply {
  radius = 5f
}

val fixtureDef = FixtureDef().apply {
  restitution = 0.7f
  shape = circleShape
}

val body: Body = world.createBody(bodyDef)
body.createFixture(fixtureDef)
circleShape.dispose()

With the body builder, it's a lot more compact. To start off, all builders are reusable after calling build.

val builder = BodyBuilder(world)
val bodyDefBuilder = BodyDefBuilder()
val fixtureDefBuilder = FixtureDefBuilder()

With that in mind, to reproduce the creation process above, all we have to do is this:

bodyDefBuilder
  .position(20f, 30f)
  .type(BodyDef.BodyType.DynamicBody)

fixtureDefBuilder
  .circle(5f)
  .restitution(0.7f)

builder
  .withBodyDef(bodyDefBuilder)
  .withFixtureDef(fixDefBuilder)
  .build()

This feels easier to read, and although not fully-featured, still grants a fair amount of customization options.