使用libgdx对Box2D进行封装:flixel-gdx-box2d

jopen 9年前

FlxBox2D是一个通过使用libgdx对Box2D进行封装,它使得在flixel中使用Box2D编写代码变得更加简单。

使用libgdx对Box2D进行封装:flixel-gdx-box2d

Getting started

Before you start writing code with Box2D it is recommended you read the manual first. Box2D is not something simple to start off directly. The manual can be downloaded here: http://box2d.org/manual.pdf. If you don’t like reading the manual, there is also a website that teaches you from scratch: http://www.iforce2d.net/b2dtut/introductions. Either way, you shouldn’t proceed if you haven’t read the stuff.

Things you need to know about FlxBox2D

The prefix of FlxBox2D classes begins with B2Flx. Some variables are already set as default or differ from Box2D. The table below shows which.

B2FlxB.RATIO (32f) The ratio from meters to pixels.
B2FlxB._gravity (0, 9.8f) The gravity.
B2FlxB.contact The contact manager used for collision detection is intiliazed on setup.
B2FlxShape.resetAngle (true) Resets the angle to 0 when it reaches 360 or -360 to prevent overflow.
Radians to Degrees Box2D uses radians, but FlxBox2D converts them to degrees.

To get Box2D objects working your state needs to inherit B2FlxState instead FlxState. The World will be created in B2FlxState and this will also avoid the spiral of death, because flixel uses delta time step while Box2D uses fixed time step. B2FlxState solves this by using fixed delta time step.

Depending on your game requirements, choose one of the collision algorithms and don’t mix them.

Shapes

If you’ve read the manual, then you saw some snippets how to create a shape. It requires a fixture and body definition before it finally become a body that can freely move in the world. Fortunately FlxBox2D significantly simplify instantiation of bodies and provide a simple way to skin bodies with custom graphics.

Box shape

new B2FlxBox(50,50, 50, 50)      .setRestitution(.3f)      .setFriction(.2f)      .setDensity(.8f)      .setDraggable(true)      .create();

To make the body alive in world you need call create() at the end. There are five different shapes you can create.

Combining shapes together is also possible. You need to create a shapeless Shape and create fixtures from other shapes.

// Shapeless. Attach shapes to it.  B2FlxSprite sprite = new B2FlxSprite(200, 200).create();  B2FlxPolygon polyshape = new B2FlxPolygon(0, 0, new float[][][]      {          {{-64,-64},{32,-32},{32,32},{-32,32}}      })      .setRestitution(.3f)      .setFriction(.2f)      .setDensity(.8f);  sprite.createFixtureFromPolygon(polyshape, true);

Box2D Shapes

Class diagram of shapes

Box2D Shape Diagram

Joints

There are 10 different joints. All of them are created about the same way.

B2FlxBox box1 = createBox(25, 25, 50, 50);  B2FlxBox box2 = createBox(100, 25, 50, 50);  new B2FlxDistanceJoint(box1, box2)      .setAnchorA(box1.body.getWorldCenter())      .setAnchorB(box2.body.getWorldCenter())      .setShowLine(true)      .create();

Distance Joint

Read the manual what a specific joint does and is used for.

Class diagram of joints

Box2D Joint Diagram

Debug

To enable to debug mode, you need to set FlxG.debug to true in your class that extends FlxGame. The debug settings can be found in B2FlxDebug.

Note: the boundingbox of FlxSprite is not visible anymore when using Box2D objects.

Collision usage in FlxBox2D

At default the fixtures are able to collide with other fixtures, but it’s also possible to setup collision filters to have a better control over which fixtures can collide with each other. The collision filter has three variables:

categoryBits The shape that belongs to.
maskBits This states the categories that this shape would accept for collision. I'm categoryBits and collide with MaskBits.
groupIndex Collision groups allow a certain group of objects to never collide (negative) or always collide (positive). Zero means no collision group. Non-zero group filtering always wins against the mask bits.

This tutorial (http://www.aurelienribon.com/blog/2011/07/box2d-tutorial-collision-filtering/) clearly tells how collision in Box2D works and it’s recommended you read this first.

The collision in Box2D happens with a listener. This means the collision check mustn’t be put inside the update loop. The event listener is created on default when B2FlxState is initialized. In FlxBox2D the B2FlxContactManager makes things a little easier. The only things you need to do are choosing the contact type and pass the categoryBits or groupIndex and the callback. Take a look below for an example.

short PLAYER = 0x0001;  short ENEMY = 0x0002;    B2FlxBox player = new B2FlxBox(8, 10, 64, 64)          .setGroupIndex(1)          .setCategoryBits(PLAYER)          .setMaskBits(ENEMY)          .create();    B2FlxBox enemy = new B2FlxBox(20, 10, 64, 64)          .setGroupIndex(1)          .setCategoryBits(ENEMY)          .setMaskBits(PLAYER)          .create();    B2FlxB.contact.onBeginContact(PLAYER, ENEMY, onHit)    IB2FlxLister onHit = new IB2FlxListener()  {      @Override      public void onContact(B2FlxShape sprite1, B2FlxShape sprite2, Contact contact, Manifold oldManifold, ContactImpulse impulse)      {          sprite1.hurt();      }  }

player object can collide with enemy object (maskbit ENEMY vs PLAYER) and both got positive groupIndex (1). This example was single object handling, but you can also collide single against group and group against group. Check this example for the rest of the code.

Examples:

  • Demos to learn other classes.
  • Advanced stuff with Box2D at iforce2d.

项目主页:http://www.open-open.com/lib/view/home/1413882191934