box2d 刚体 编辑器

原始地址:

  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 and circles. 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 multiple fixtures. 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 the reference 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 my tutorial 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 the getPosition() 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!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员入门进阶(免费辅导开题报告)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值