【发布时间】:2019-07-12 18:50:40
【问题描述】:
我有一个不只是一个盒子或圆形的纹理,我的身体需要与这个形状相同,所以我想组合多个身体来达到我想要的形状,这有可能吗?或者有更好的方法吗?我正在使用带有 libgdx 框架的 java。
【问题讨论】:
我有一个不只是一个盒子或圆形的纹理,我的身体需要与这个形状相同,所以我想组合多个身体来达到我想要的形状,这有可能吗?或者有更好的方法吗?我正在使用带有 libgdx 框架的 java。
【问题讨论】:
body 的形状由Fixture 实例定义。由于 body 可以有多个固定装置,因此您可以根据需要组合多种形状。
要创建许多固定装置,您可以多次调用 createFixture 方法与其他 FixtureDef 对象类似
FixtureDef fd1 = new FixtureDef();
FixtureDef fd2 = new FixtureDef();
...
fd1.shape = shape1;
fd2.shape = shape2;
...
body.createFixture(fd1);
body.createFixture(fd1);
尽管请注意 Box2D 支持的不仅仅是圆形和矩形,它提供了ChainShape,让您可以创建任何您想要的形状
ChainShape weird = new ChainShape();
weird.createLoop( new float[]{vertice1x, vertice1y, vertice2x, ...});
要加入主体,有 Joint(看看here)机制,但我想这不是你想要的
【讨论】:
是的,您可以按照以下步骤进行操作
有适合您工作的 PolygonShape 或 ChainShape 选项
第 1 步:定义主体。
BodyDef bd = new BodyDef();
Body body = box2d.world.createBody(bd);
第 2 步:定义形状。
ChainShape chain = new ChainShape();
第 3 步:配置形状。 ChainShape 对象是一系列连接的顶点。要创建链,我们必须首先指定一个顶点数组(每个顶点都作为一个 Vec2 对象)。 为了创建带有顶点的链,然后将数组传递给一个名为
的函数createChain().Vec2[] vertices = new Vec2[2];
vertices[0] = box2d.coordPixelsToWorld(0,150);
vertices[1] = box2d.coordPixelsToWorld(width,150);
chain.createChain(vertices, vertices.length);
Shape 不是 Box2D 的一部分,除非它附加到一个实体上。即便是固定的边界,从不移动,也必须附上。
FixtureDef fd = new FixtureDef();
fd.shape = chain; A fixture assigned to the ChainShape
fd.density = 1;
fd.friction = 0.3;
fd.restitution = 0.5;
body.createFixture(fd);
多边形形状
PolygonShape ps = new PolygonShape();
ps.setAsBox(box2dW, box2dH);
Vec2[] vertices = new Vec2[4];
vertices[0] = box2d.vectorPixelsToWorld(new Vec2(-15, 25));
vertices[1] = box2d.vectorPixelsToWorld(new Vec2(15, 0));
vertices[2] = box2d.vectorPixelsToWorld(new Vec2(20, -15));
vertices[3] = box2d.vectorPixelsToWorld(new Vec2(-10, -10));
PolygonShape ps = new PolygonShape();
ps.set(vertices, vertices.length);
【讨论】:
官方测试平台示例
我强烈建议您在 GUI 上查看所有 Testbed 示例,直到找到所需的效果。
通过这样做,我能够找到以下示例:
https://stackoverflow.com/a/35667538/895245 中提到的每个主体有多个固定装置:
这是迄今为止我见过的最好的方法。
ChainShape:https://github.com/erincatto/Box2D/blob/f655c603ba9d83f07fc566d38d2654ba35739102/Box2D/Testbed/Tests/CharacterCollision.h#L56 但是如果你的形状的边缘之一不是直线,例如一个圆圈。
但是,这并没有使两个主体完全结合,如示例本身和 Box2D 手册中所示:
使用焊接接头来定义易碎结构是很有诱惑力的。但是,Box2D 求解器是迭代的 所以关节有点软。所以通过焊接接头连接的主体链会弯曲
所以它更像是一个试图以给定角度离开两个物体的旋转关节。
这些示例非常简单,将随着 Box2D 的发展而得到支持。
【讨论】:
要创建不同的形状,您可以从这些示例中获得灵感:
创建圆形。
bodyDef.type = b2Body.b2_dynamicBody;
var fixDef = new b2FixtureDef;
fixDef.density = 1000;
fixDef.friction = 0.5;
fixDef.restitution = 0.5;
fixDef.shape = new b2CircleShape(0.5);
bodyDef.position.x = 1;
bodyDef.position.y = 16;
world.CreateBody(bodyDef).CreateFixture(fixDef);
创建盒子(矩形或正方形)形状。
var fixDef = new b2FixtureDef;
fixDef.density = 100;
fixDef.friction = 5;
fixDef.restitution = 0.5;
bodyDef.type = b2Body.b2_dynamicBody;
fixDef.shape = new b2PolygonShape;
fixDef.shape.SetAsBox(0.2,1);
bodyDef.position.x =i;
bodyDef.position.y = 15.5;
world.CreateBody(bodyDef).CreateFixture(fixDef);
创建拆箱形状(多边形)。
bodyDef.type = b2Body.b2_dynamicBody;
fixDef.shape = new b2PolygonShape;
fixDef.shape.SetAsArray([
new b2Vec2(-1,0.5),//left vertex
new b2Vec2(3,-0.3),//top vertex
new b2Vec2(3,0.5),//right vertex
],3);
bodyDef.position.x =5;
bodyDef.position.y = 16;
world.CreateBody(bodyDef).CreateFixture(fixDef);
【讨论】: