2014-05-14 5 views
2

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

Screenshot

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

Мир имеет Y силы тяжести на -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); 
} 
} 
+0

У ваших тел масса? –

+0

Я распечатал их значения, и они имеют массу 1 кг. – ViliX64

+0

Вы установили гравитацию? Вы можете также заблокировать вращение тела, вы могли это сделать? – noone

ответ

4
MassData md = new MassData(); 

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

Если вы

MassData md = body.getMassData(); 

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

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

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

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

+0

Хорошо, похоже, что это работает, но StackOverflow только позволяет мне дать вам щедрость через некоторое время (1 час). Так что спасибо anwser и проявите терпение. – ViliX64

+3

Bounty будет хорошим дополнением, но я ответил, чтобы помочь вам, а не за щедрость. Удачи! – McBodik