I have created an android application similar to Not Tetris 2 using Libgdx with Box2d.
It can successfully remove a slice from the world, which obviously involves duplicating several bodies and destroying/creating fixtures. However, seemingly at random, a body with a 2x2 fixture will appear. The body and fixture are displayed using information related to the objects around it when it is created, so I narrowed its creation down to the following function:
Body duplicateBody(Body original){
BodyDef d = new BodyDef();
d.position.set(original.getPosition());
d.angle = original.getAngle();
d.linearVelocity.set(original.getLinearVelocity());
d.angularVelocity = original.getAngularVelocity();
Body dup = world.createBody(d);
dup.setType(BodyDef.BodyType.DynamicBody);
return dup;
}
I use this function in 2 different contexts:
- Making a copy of the body if a "slice" cuts one in two -- I then transfer the fixtures which are below to it.
- When a fixture is below the line then it is added to a body created for ones below
- Making a copy of the body when groups of fixtures are separated
I commented out the code responsible for the third instance and still had the 2x2 boxes spawning, so here are the functions relevant to the others:
...
if (below && !above) {
//copy fixture, add copy to lower body and remove original
Body top = fixture.getBody();
FixtureDef n = new FixtureDef();
PolygonShape s = new PolygonShape();
s.set(getLocalVerticesOfFixture(fixture));
n.shape = s;
n.density = fixture.getDensity();
//create lower body if a lower one doesn't already exist
if (!topBottomPairs.containsKey(top)) {
Body dup = duplicateBody(top);
topBottomPairs.put(top, dup);
}
//delete fixture
remove.add(fixture);
Fixture f = topBottomPairs.get(top).createFixture(n);
s.dispose();
}
...
if (below && above) {
//copy fixture, add copy to lower body, but keep original on upper as it needs to split
FixtureDef n = new FixtureDef();
PolygonShape s = new PolygonShape();
s.set(getLocalVerticesOfFixture(fixture));
n.shape = s;
n.density = fixture.getDensity();
Body top = fixture.getBody();
//create lower body if a lower one doesn't already exist
if (!topBottomPairs.containsKey(top)) {
Body dup = duplicateBody(top);
topBottomPairs.put(top, dup);
}
Fixture second = topBottomPairs.get(top).createFixture(n);
s.dispose();
}
....
private Vector2[] getLocalVerticesOfFixture(Fixture fixture) {
PolygonShape shape = ((PolygonShape) fixture.getShape());
Vector2[] localVertices = new Vector2[shape.getVertexCount()];
for (int i = 0; i < shape.getVertexCount(); i++) {
localVertices[i] = new Vector2();
shape.getVertex(i, localVertices[i]);
}
return localVertices;
}
I also have this remove fixture function which runs on all fixtures I want to remove:
private void smartDeleteFixture(Fixture f){
f.getBody().destroyFixture(f);
if(f.getBody().getFixtureList().size == 0){
world.destroyBody(f.getBody());
}
}
Nowhere do I create vertices, let alone a fixture of a 2x2 shape. I was wondering if this duplication function has any flaws, or if I stumbled upon some "default shape" that box2d uses.
Edit: I have removed anything not related to the manipulation of box2d bodies. Hope that helps