box2d 刚体 编辑器

来源:互联网 发布:淘宝积分怎么查手机 编辑:程序博客网 时间:2024/05/16 13:46

原始地址:

  http://www.aurelienribon.com/blog/projects/physics-body-editor/


Physics Body Editor

Introduction

From the editor to the game

Physics Body Editor is all about making your life easier with physics engines. Specifically, it targets the creation of collision shapes for your game objects: we call them rigid bodies. It can also let you combine these objects together and link them with joints to create complex objects: we call them dynamic objects.

The problem we want to solve is as follows: have a look at the image on the right, I wanted to create a bottle that can hold objects inside it. At first, I used a drawing tool to draw my shape points over the bottle image, and I reported the values in my game. For each point, I had to convert from pixel units to world units of course. Boring. Oh, and guess what? It didn’t work! Indeed,physics engines usually only work with convex polygons! On to decompose the shape into multiple convex polygons by hand… More than boring. And of course, each time I wanted to do a little change, I had to go over the same process.

I guess you understand why such automated tool can be handy: it converts pixel units to world units, decomposes the shape into multiple convex polygons, and lets you test the result directly!

Features

  • Automatically decomposes concave shapes into convex polygons,
  • Automatically traces your images if needed,
  • Supports multiple outlines for a single body,
  • Supports polygon and circle shapes,
  • Reference point location can be changed,
  • Visual configurable grid with snap-to-grid option,
  • Built-in collision tester! Throw balls at your body to test it,
  • Loader provided for LibGDX game framework,
  • Simple export format (JSON), to let you create your own loader for any framework in any language.


Download

The latest version of the application can be downloaded from its project page. As it is written in Java, it should be working under Windows, MacOS and most Linux distributions.

Project repository:
http://code.google.com/p/box2d-editor/

Download page (application, loaders and demos):
http://code.google.com/p/box2d-editor/downloads/list

The application uses the following technologies:

  • LibGDX, the most awesome game dev library, for the rendering of the canvas area,
  • Box2d, as the embedded physics engine (available in Java thanks to libGDX),
  • Farseer engine, for its auto-trace and polygon decomposition algorithms.

Issues

Under a linux distribution, iBus is known to cause problems with Java software, and may prevent you from using the CTRL modifier key.

Application Manual

Get started quickly!

Here is a video tutorial to get you quicky up and running. It shows how to create a project, how to add a new body, and how to define its collision shape. The video quality is not awesome at all (sorry about that), so don’t look at it to appreciate the user experience of the application but only to learn the basic commands.

[youtube=http://www.youtube.com/watch?v=KASY91EiTXQ]

Polygons and circles

There is two kind of shapes that can be created: polygons andcircles. To create a polygon shape, all you have to do is to enable the creation mode, and to click anywhere on the screen. Each click will add a point to the polygon, and when you want to close it, just click on the first point. To create a circle shape, you need to hold CTRL or C key, and then click once to define the center of the shape, and a second time to define its radius.

Keyboard shortcuts

Several keyboard shortcuts exist to make your life easier:

  • TAB to switch between creation, edition and test modes,
  • BACKSPACE to delete the selected points,
  • ENTER to insert new points between the selected ones,
  • ESC to cancel the creation of a shape before you close it.

Auto-trace

The tool supports an auto-trace feature that may help you in many occasions with a little practice. Auto-trace algorithms are generally far less precise than your hand, but with a few refinement steps, you can create complex shapes very quickly.

Auto-trace feature is only available when there is no existing shape previously defined, and if an image is associated to your body. It works on the alpha channel of the image, and takes 4 parameters.Hull tolerance defines how precisely you want the contour of your image to be followed (a higher value means a lower precision).Alpha tolerance ranges between 0 and 255 and defines the alpha limit between a solid pixel and an empty pixel. When activated, multi-part detection will try to trace multiple shapes, and hole detection will try to detect a hole in an image. The success of the two last option is not guaranteed.

Reference point

In Physics Body Editor, you define a body for each image, and this body is made of multiplefixtures. A fixture is basically a shape (polygon or circle) associated to some parameters, like its density and its friction. A body is located in the world with a single point, called thereference point. Its fixtures are placed around this reference point.Note that this reference point has nothing to do with its mass center. Indeed, the rotation point of your body is its mass center. The reference point has no impact on the physics simulation. It is just a convenience point to get the position of your body relatively to this reference point. That’s it for the theory of physics engines.

By default, the reference point of a body is at the bottom left corner of its associated image. This means that when you will position the body in your game world, its fixtures will all be at the right of the location. You can move this reference point in Physics Body Editor in edition mode: it is the red cross with a circle.

Loader and game objects

Note: the following code snippets are extracted from the loader-libgdx-demo project. They are written in Java, and target the LibGDX game framework. However, they should be easy to understand, and easy to port to any other language.

There are two important things when you want to use your project file in your game:(1) attaching the fixtures to your bodies, and (2) drawing the associated image at the right place. In physics engines, bodies are models: they are not related to how you will render them on screen at all. See mytutorial about the separation between models and render to understand.

First step is easy, the provided loader does everything for you. Note that at line 7, the position correspond the the world position of the body reference point. Here we set it at world coordinates (0,0).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private void createBottle() {
    // 0. Create a loader for the file saved from the editor.
    BodyEditorLoader loader =new BodyEditorLoader(Gdx.files.internal("data/test.json"));
  
    // 1. Create a BodyDef, as usual.
    BodyDef bd =new BodyDef();
    bd.position.set(0,0);
    bd.type = BodyType.DynamicBody;
  
    // 2. Create a FixtureDef, as usual.
    FixtureDef fd =new FixtureDef();
    fd.density =1;
    fd.friction =0.5f;
    fd.restitution =0.3f;
  
    // 3. Create a Body, as usual.
    bottleModel = world.createBody(bd);
  
    // 4. Create the body fixture automatically by using the loader.
    loader.attachFixture(bottleModel,"test01", fd, BOTTLE_WIDTH);
}

Now that we have our model entirely built, we need to draw the corresponding image at its location. LibGDX draws images with a reference to their bottom left corner. Therefore, if you left the reference point at the bottom left corner of your body, you can directly place the image at the location of the reference point (returned by Box2d engine with thegetPosition() method).Else, if you changed the reference point location, you need to take it into account to draw the image.

Therefore, you need to store the reference point somewhere for later use:

1
bottleModelOrigin = loader.getOrigin("test01", BOTTLE_WIDTH).cpy();

Finally, in your render method, you can draw the image at the reference point location, offset by its local coordinates relatively to the image bottom left corner:

1
2
3
4
5
6
7
8
9
public void render() {
    Vector2 bottlePos = bottleModel.getPosition().sub(bottleModelOrigin);
  
    bottleSprite.setPosition(bottlePos.x, bottlePos.y);
    bottleSprite.setOrigin(bottleModelOrigin.x, bottleModelOrigin.y);
    bottleSprite.setRotation(bottleModel.getAngle() * MathUtils.radiansToDegrees);
  
    ...
}

That’s all, you should now be up and running!

0 0
原创粉丝点击