[LibGDX + Box2D] Drawing Bitmap Fonts with Box2D World

I have this issue and I am not quite sure what to do.

I have a Box2D world that is 30 meters width and 15 meters height, the problem being this technically translates to 30 pixels by 15 pixels when you try to draw anything not related to Box2D using SpriteBatch and BitmapFont. SpriteBatch is fine and easy to scale, since it is as simple as setScale(1,1) 90% of the time, sometimes a little tweaking is required.

However, when I try to draw a font onto the screen…I get this HUGE character, normally just a small part of it due to its size. I have tried:

font.setScale(x, y)
font.scale(xy)

Both of these work to a small degree, I am having to put in a stupidly small float in order to scale it accordingly, such as 0.0015f.

So I have done this and my font appears on the screen, so I set it to the correct position and think everything is ok. This font I am drawing is to keep track of the score, so every iteration of the game loop the score adjusts, whenever it changes from 0 to 1, it disappears off the screen.

Now even worse, if I want to put any text information such as

"Player 1: " +p1Score

, this gets realllllly screwy. Now the score counter is all messed up and somewhere else on the screen, the word Player 1 mainly consists of letters such as PYE as if some characters are too large to fit in.

Does anyone have a work around for this?

Here is my drawing code for reference:

		batch.setProjectionMatrix(cam.combined);
		cam.update();
		batch.begin();
		scoreFont.draw(batch,"" + p1Score, 13f, 14.5f);
		scoreFont.draw(batch, "" +p2Score, 16, 14.5f);
		pongTableSprite.draw(batch);

//		// Iterate through bodies, get sprites
		world.getBodies(tmpBodies);
		for (Body body : tmpBodies) {
			if (body.getUserData() instanceof Sprite) {
				Sprite sprite = (Sprite) body.getUserData();
				sprite.setPosition(
						body.getPosition().x - sprite.getWidth() / 2,
						body.getPosition().y - sprite.getHeight() / 2);
				sprite.setRotation(body.getAngle() * MathUtils.radiansToDegrees);
				sprite.setOrigin(sprite.getWidth() / 2, sprite.getHeight() / 2);
				sprite.draw(batch);
			}
		}

		batch.end();

This code here is in the show method, this is where the font gets it’s scale set:

		// Create fonts
		scoreFont = new BitmapFont(Gdx.files.internal("fonts/headingwhite.fnt"));
		scoreFont.setScale(0.01f, 0.01f);

First of all, it’s not a good idea to have a 1:1 meter per pixel ratio. This will be a problem for box2d. To quote https://code.google.com/p/box2d/wiki/FAQ

However, for stuff like static non-box2d objects, You can have a different camera. For font drawing, don’t use the box2d camera, instead create a new camera that has the width and height of the screen (in pixels) and use that. This will make things easier. When to think about it, You actually don’t need a cam for box2d, just need to convert the box coordinates to pixels. The FAQ has a small section about it.

Thank you for the reply, yeah it seems I was using conversion wrong…well not at all.

For anyone interested I am creating a Main Menu screen for a game that will have 3 signs (buttons eg, play, exit, settings) that hang from the top of the screen via chains (rope joints).

So when I am creating these signs I must convert from pixels to meters, i have chosen to have 10 by 10 (width, height).

In order to convert from meters to pixels I am using a constant:

public static final float PtoM = 160f;

I then create my sign using the following code:

public Sign(World world, Sprite sprite, float posX, float posY){
		
		// Create shape
		PolygonShape signShape = new PolygonShape();
		signShape.setAsBox(1* MainMenuScreen.PtoM, 0.5f * MainMenuScreen.PtoM);
		
		// Create body and fixture definition
		BodyDef bodyDef = new BodyDef();
		FixtureDef fixtureDef = new FixtureDef();
		
		bodyDef.type = BodyType.DynamicBody;
		bodyDef.position.set(posX, posY);
		
		fixtureDef.shape = signShape;
		fixtureDef.friction = 1;
		fixtureDef.restitution = 1;
		fixtureDef.density = 1;
		
		body = world.createBody(bodyDef);
		fixture = getBody().createFixture(fixtureDef);
		sprite.setSize(1 * 2 * MainMenuScreen.PtoM, 0.5f * 2 * MainMenuScreen.PtoM);
		System.out.println("Sign Created!");
		
		body.setUserData(sprite);
		
		
	}

As you can see I am setting the box to be 1 meter wide and half meter in height, I then multiply that by the constant in my main menu class, this gives the sign a pixel size of 160 by 80.

I hope this helps anyone with a similar problem, really I just never read the FAQ/Guide clearly, thanks.