Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Problemilla con LibGDX y Box2D

Iniciado por NullPointerException, 22 de Febrero de 2014, 11:53:46 PM

« anterior - próximo »

NullPointerException

Hola gente,

Estoy intentando implementar fisicas con LibGDX y Box2D, pero hay un problema.

Creo un polygonShape como una Box, luego cuando lo pongo en juego, la gravedad apenas hay, parece como si fuera una pluma que flotara en el aire.

Y he mirado de coger y aumentar bastante la gravedad (hablamos de valores de 9999999) y la densidad también, pero ná, el objeto cae despacio.

Y tambien le aplico al body el angularimpulse pero no reacciona a eso.

No sé yo si hago algo mal. Las dimensiones del objeto son 1000x500 metros.

Voy a poner el codigo:

private void createPhysicBody() {
BodyDef bodyDef=new BodyDef();
bodyDef.type=BodyType.DynamicBody;

bodyDef.position.set(UnitConversor.pixelsToMeters(area.x),
UnitConversor.pixelsToMeters(area.y));
bodyDef.angle=0;
body = world.createBody(bodyDef);

PolygonShape shape = new PolygonShape();
shape.setAsBox(UnitConversor.pixelsToMeters(area.width/2),
UnitConversor.pixelsToMeters(area.height/2));

FixtureDef fixture = new FixtureDef();
fixture.density=1f;
fixture.restitution=0f;
fixture.shape=shape;

body.createFixture(fixture);

shape.dispose();

body.setUserData(this);
body.applyAngularImpulse(25, true);


}


Considerad que el área es de 1000x500 . Si lo pongo más pequeño luego se ve diminuto

YaW

Box2D está diseñado para funcionar con objetos pequeños, de entre 0.1 y 10m. Mira la documentación oficial, especialmente el punto 1.7: http://www.box2d.org/manual.html

El mundo de Box2D tienes que hacerlo pequeño y luego representarlo como tu quieras de grande, pero todos los calculos y internamente tiene que ser pequeño.

NullPointerException

El problema es que si lo pongo pequeño apenas se ve en la pantalla, como podría hacer para que se viera más grande, pero usando valores pequeños en box2d?

Sé que tiene algo que ver con la cámara, el problema es que yo necesito cambiar el viewport dependiendo del tamaño, porque quiero adaptarlo a todas las resoluciones y no sé como atacar el tema.

//CAMARA
private final int NATIVE_WIDTH=720;
private final int NATIVE_HEIGHT=1280;
private final float ASPECT_RATIO=(float)NATIVE_WIDTH/(float)NATIVE_HEIGHT;
private Rectangle viewport;

private OrthographicCamera camera;
private SpriteBatch batch;

//FISICAS
private Box2DDebugRenderer debugRenderer;
private boolean boxdebug=true;
private int velocityIterations=6;
private int positionIterations=2;
private World world;

//OTROS
private AssetManager resources;
private Scene escena;

@Override
public void create() {
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();

camera = new OrthographicCamera(1, h/w);
camera.setToOrtho(false, NATIVE_WIDTH, NATIVE_HEIGHT);
batch = new SpriteBatch();


world=new World(new Vector2(0,-10f), true);
debugRenderer=new Box2DDebugRenderer();

resources=new AssetManager();

escena=new Scene(world);
LoadGame();
}

private void LoadGame() {
resources.load("data/images/avispa_spritesheet.png",Texture.class);
resources.load("data/images/fondos/cielo_dia.png",Texture.class);
resources.finishLoading();

escena.Load(resources);
}

@Override
public void dispose() {
batch.dispose();
}

@Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);

//Clear previous frame
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

camera.position.set( NATIVE_WIDTH /2, NATIVE_HEIGHT /2, 0f);
//Update camera
camera.update();

//set viewport
Gdx.gl.glViewport((int)viewport.x,(int)viewport.y, (int)viewport.width, (int)viewport.height);


//camera.zoom=0.03f;
Gdx.graphics.setVSync(true);

escena.Update(Gdx.graphics.getDeltaTime());

batch.setProjectionMatrix(camera.combined);
escena.Draw(batch);

if(boxdebug) debugRenderer.render(world, camera.combined);
world.step(1/45f, velocityIterations, positionIterations);
}

@Override
public void resize(int width, int height) {

float aspectratio=(float)width/(float)height;
float scale=1f;
Vector2 crop=new Vector2(0f,0f);
       
if(aspectratio > ASPECT_RATIO)
        {
            scale = (float)height/(float)NATIVE_HEIGHT;
            crop.x = (width - NATIVE_WIDTH*scale)/2f;
        }
        else if(aspectratio < ASPECT_RATIO)
        {
            scale = (float)width/(float)NATIVE_WIDTH;
            crop.y = (height - NATIVE_HEIGHT*scale)/2f;
        }
        else
        {
            scale = (float)width/(float)NATIVE_WIDTH;
        }

        float w = (float)NATIVE_WIDTH*scale;
        float h = (float)NATIVE_HEIGHT*scale;
        viewport = new Rectangle(crop.x, crop.y, w, h);
        escena.setViewport(viewport);
}

YaW

Tienes que definir un ratio entre el mundo de las fisicas y el mundo gráfico (que son dos cosas diferentes y no tienen nada que ver).

Por ejemplo estos son los valores que uso yo:

public static final float WORLD_TO_BOX = 0.02f;
public static final float BOX_TO_WORLD = 50.0f;


Cada vez que vayas a relacionar el mundo de Box2d con tus gráficos tienes que usar estos parametros para convertir todos los datos. Por ejemplo, pongamos que tu personaje principal está en la posición x=400,y=500, para calcular la posición de su body harías:

float xBody = 400 * WORLD_TO_BOX -> 8
float yBody = 500 * WORLD_TO_BOX -> 10


Cuando necesites al contrario pues lo mismo, teniendo el ancho o posición de tu body para calcular el del sprite simplemente tendrías que multiplicar por el BOX_TO_WORLD para tener el dato que tienes que usar en el gráfico.

NullPointerException

Perdon por la larga tardanza. Yo hacia el box to world, pero el problema era la camara, que no se reajustaba bien.

AL final decidi cambiarme a Unity. Todo el trabajo lo hice rapidamente y ya casi la tengo hecha desde entonces, el problema me lo da ahora la API de Facebook que no me deja crear posts.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.