java - tutorial - Box2d libgdx, un poco confundido acerca de los píxeles a los metros cosas
java game development with libgdx (1)
Me gusta lo que estás haciendo, pero podría ser un poco diferente.
Puede ser un poco exagerado pero aquí está mi puerto jucl
Entonces solo tengo clases de utilidad, es decir:
public class Pixel {
public static float toMeter(float pixels) {
return (float)LengthConversions.Pixel2SIf(pixels);
}
public static Vector2 toMeter(Vector2 vecPixel) {
return new Vector2(Pixel.toMeter(vecPixel.x), Pixel.toMeter(vecPixel.y));
}
}
public class Meter {
public static final float METERS_PER_PIXEL = (float) LengthConversions.SI_PIXEL;
public static float toPixel(float meter) {
return (float)LengthConversions.SI2Pixelf(meter);
}
}
En mi inicialización:
int graphicsWidth = Gdx.graphics.getWidth();
int graphicsHeight = Gdx.graphics.getHeight();
CAMERA_WIDTH_METERS = Pixel.toMeter(graphicsWidth);
CAMERA_HEIGHT_METERS = Pixel.toMeter(graphicsHeight);
Luego en mis clases de juego (como tu clase de jugador). En mi caso, era un juego de pinball, así que tengo Flipper, Ball, Bumper, etc. Tengo un método @Override render () donde sincronizo el sprite con el cuerpo de la física.
Aquí hay un archivo de ejemplo ... parece desordenado, pero podría ser útil.
Entonces entiendo el concepto. La idea es que box2d funcione más o menos en metros, por lo que debe realizar una conversión de píxeles a este. Tiene sentido. Estaba siguiendo el tutorial / introducción a box2d aquí . Menciona hacer la conversión y le da algunos ejemplos de cantidades para usar. Ahora, eso está muy bien, pero me parece que cuando uso estas técnicas, la caja del depurador no parece mostrarse donde deberían. Sin embargo, la colisión funciona como se esperaba.
En mi clase GameScreen, así es como inicializo el terreno:
ground = new BodyDef();
// set the position half way up the ground
ground.position.set(0,16 * GameScreen.WORLD_TO_BOX);
groundBody = world.createBody(ground);
groundShape = new PolygonShape();
// make the height 16px so it doubles to 32
groundShape.setAsBox(Gdx.graphics.getWidth() * GameScreen.WORLD_TO_BOX, 16.0f * GameScreen.WORLD_TO_BOX);
groundBody.createFixture(groundShape, 0.0f);
Mi método de renderizado en esa pantalla es así:
public void render(float delta) {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
camera.update();
stateTime += Gdx.graphics.getDeltaTime();
batch.begin();
batch.draw(background, 0, Gdx.graphics.getHeight() - 512, 512, 512);
batch.draw(trailingBackground, 512, Gdx.graphics.getHeight() - 512);
int heightToCover = Gdx.graphics.getHeight() - 512;
int widthToCover = Gdx.graphics.getWidth();
for(int w = 0; w < widthToCover; w += 32) {
for(int h = 0; h < heightToCover; h += 32) {
batch.draw(lightBackgroundTile, w, h, 32, 32);
}
}
player.update();
player.render(stateTime, batch);
batch.end();
levels.get(currentLevel).render(camera);
// physics updates
world.step(1/60f, 6, 2);
debugRenderer.render(world, camera.combined);
}
Aquí está el constructor de la clase de jugador, para que pueda ver cómo estoy configurando sus objetos de colisión box2d. También pegué el método de actualización que se llama en el ciclo de renderizado anterior para ajustar la posición de los sprites.
public Player(int x, int y, World world) {
super();
playerTexture = new Texture(Gdx.files.internal("assets/hero.png"));
init(x, y, 128, 128, playerTexture, false, world);
bodyDef = new BodyDef();
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set(x * GameScreen.WORLD_TO_BOX, y * GameScreen.WORLD_TO_BOX);
body = getWorld().createBody(bodyDef);
collisionBox = new PolygonShape();
collisionBox.setAsBox(32 * GameScreen.WORLD_TO_BOX, 64 * GameScreen.WORLD_TO_BOX, new Vector2(64 * GameScreen.WORLD_TO_BOX, 64 * GameScreen.WORLD_TO_BOX), 0.0f);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = collisionBox;
fixtureDef.density = 10f;
fixtureDef.friction = 0.4f;
fixtureDef.restitution = 0f;
body.createFixture(fixtureDef);
collisionBox.dispose();
addFrame(0, 0, 128, 128);
}
public void update() {
this.setX((int) ((body.getPosition().x) * GameScreen.BOX_TO_WORLD));
this.setY((int) ((body.getPosition().y) * GameScreen.BOX_TO_WORLD));
}
Ahora, cuando elimino la multiplicación de esos flotantes estáticos en los diversos cálculos, tamaños, etc., la colisión sigue siendo correcta y aparece el cuadro del depurador. Sin embargo, pasar los píxeles brutos a box2d se siente mal. ¿Hay algo que me falta aquí sobre por qué las cajas de depuración no aparecen como están?