LibGDX + Box2D вращение

Как применить автоматическое вращение (как в реальном мире) в Box2D с помощью LibGDX? Это не выглядит реалистично (см. Рисунок ниже).

Скриншот

В реальном мире блоки будут вращаться и падать, но в этом симуляции это не так.

У Мира Y-Gravity на уровне -9.81 (поэтому падение и столкновение работает отлично). Вот код, где я создаю прямоугольники:

PolygonShape pShape = new PolygonShape();
FixtureDef fDef = new FixtureDef();
BodyDef bDef = new BodyDef();
Body body;

pShape.setAsBox(width, height);
bDef.position.set(x, y);
bDef.type = type;
fDef.shape = pShape;
fDef.density = 1.0f;
fDef.friction = 0.3f;
body = world.createBody(bDef);
body.createFixture(fDef);
body.setUserData(this);
MassData md = new MassData();
md.mass = 5;
body.setMassData(md);

Код для основного класса игры:

public class Game implements ApplicationListener {

public static int WIDTH;
public static int HEIGHT;

World world;
Box2DDebugRenderer dr;
OrthographicCamera cam;
float time;
final float P = 1/60f;
final static int C = 100;

public void create() {
Gdx.gl.glClearColor(.1f, .1f, .1f, 1.0f);
WIDTH = Gdx.graphics.getWidth();
HEIGHT = Gdx.graphics.getHeight();
world = new World(new Vector2(0, -9.8f), false);

dr = new Box2DDebugRenderer();
cam = new OrthographicCamera();
cam.setToOrtho(false, WIDTH/C, HEIGHT/C);

new Block(world, BodyType.StaticBody, 2,        HEIGHT,     0,          HEIGHT);
new Block(world, BodyType.StaticBody, 2,        HEIGHT,     WIDTH-40,   HEIGHT);
new Block(world, BodyType.StaticBody, WIDTH,    2,          WIDTH,      HEIGHT);
new Block(world, BodyType.StaticBody, WIDTH,    2,          WIDTH,      0);
}

public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
input();

dr.render(world, cam.combined);

time += Gdx.graphics.getDeltaTime();
while(time >= P) {
update();
time -= P;
}
}

public void update() {
world.step(P, 5, 5);
}

public void input() {
if(Gdx.input.isTouched()) {
new Block(world, BodyType.DynamicBody, 50, 20, Gdx.input.getX(), HEIGHT-Gdx.input.getY());
}
}

public void dispose() { }
public void pause() { }
public void resize(int arg0, int arg1) { }
public void resume() { }
}

Код для класса блока:

public class Block {

public Block(World world, BodyType type, float width, float height, float x, float y) {

PolygonShape pShape = new PolygonShape();
FixtureDef fDef = new FixtureDef();
BodyDef bDef = new BodyDef();
Body body;

pShape.setAsBox(width/Game.C, height/Game.C);
bDef.position.set(x/Game.C, y/Game.C);
bDef.type = type;
fDef.shape = pShape;
fDef.density = 1.0f;
fDef.friction = 0.3f;
body = world.createBody(bDef);
body.createFixture(fDef);
body.setUserData(this);
body.setFixedRotation(false);
MassData md = new MassData();
md.mass = 5;
body.setMassData(md);
}
}

2

Решение

MassData md = new MassData();

дает нулевую инерцию вращения: md.I == 0 поэтому коробка не вращается.

Если вы делаете

MassData md = body.getMassData();

у вас будет масса и инерция вращения в соответствии с вашей текущей плотностью.

Лучший способ изменить массу и получить правильную инерцию вращения — рассчитать ее самостоятельно в соответствии с вашей новой массой, например:

float massScale = [newMass] / md.mass;
md.mass *= massScale;
md.I *= massScale;

Таким образом вы сохраните правильную точку вращения и будете иметь физически правильную инерцию.

4

Другие решения


По вопросам рекламы [email protected]