I am currently having problems getting an easy to manage system of scaling my units for use with box2D. Normally I would create virtual units to go along with me viewport and camera but since I am using a screen viewport this is not as easy as it seems. I have tried scaling my viewport by setting the units per pixel to 1/100 which will then scales my world by 100 times. Then I set set my sprite batch projection to be 1/100 as well as my tiles map renderer scale to be 1/100 this led to my box2D elements of size .64 to be 64 pixels large which leads to a good looking simulation as well as a good size. The only problem is then any sprite I use must also be scaled with a scale of 1/100. Also my scene 2d HUD must also be scaled. This works but it is confusing to manage and very time consuming to write out all the scaling etc. I am looking to see if there is a way to use world units where 1 world unit is 100 pixels to make my box2D elements and use screen coordinates for the rest of my drawing etc. Also if there is an easier way to do this that I am not thinking of please let me know. I will try to post code later tonight when I am back at my computer.
EDIT: I created a test project to work on just the scaling factor of my game and here is my test code.
@Override
public void create () {
camera = new OrthographicCamera();
camera.translate(new Vector3(camera.viewportWidth / 2, camera.viewportHeight / 2, 0));
vp = new ScreenViewport(camera);
vp.setUnitsPerPixel(1/100f);
batch = new SpriteBatch();
img = new Texture("badlogic.jpg");
sprite = new Sprite(img);
sprite.setScale(1/100f);
world = new World(new Vector2(0, (float) -9.8), true);
BodyDef bdef = new BodyDef();
bdef.type = BodyType.DynamicBody;
bdef.position.set(1, 1);
body = world.createBody(bdef);
FixtureDef fdef = new FixtureDef();
PolygonShape shape = new PolygonShape();
shape.setAsBox(1, 1);
fdef.shape = shape;
body.createFixture(fdef);
dr = new Box2DDebugRenderer();
map = new TmxMapLoader().load("Levels/bricksTest.tmx");
mapRenderer = new OrthogonalTiledMapRenderer(map, 1 / 100f);
}
@Override
public void render () {
camera.update();
sprite.setX(body.getPosition().x - sprite.getWidth() / 2);
sprite.setY(body.getPosition().y - sprite.getHeight() / 2);
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
mapRenderer.setView(camera);
mapRenderer.render();
batch.setProjectionMatrix(camera.combined);
batch.begin();
sprite.draw(batch);
batch.end();
world.step(Gdx.graphics.getDeltaTime(), 6, 2);
dr.render(world, camera.combined);
}
@Override
public void resize(int width, int height) {
vp.update(width, height, true);
}
This code runs and produces the expected results, but I feel there has to be some easier way. Also ignore any of the size numbers/horrible sloppiness of this code because this is only a test project and is not from my actual game.
This is a picture of the final result. Note: The box2D box is not the same size as the image because I wanted the box to be about the size of a character from my game for this test. I also moved the position of the box to x = 5 and y = 5 so it is easier to see.