2

I have a BitmapFont that is displaying a player's score as he moves across the screen at a constant rate. Because the player is always moving, I have to recalculate at what position I draw the font every frame. I use this code.

    scoreFont.setScale(4f, 4f);
    scoreFont.draw(batch, "" + scoreToShow, playerGhost.pos.x + 100f, 600f);
    playerGhost.render(batch);
  • The problem? The font won't stop shaking. It's only a couple of pixels worth of vibration, but it's slightly noticeable. It's more noticeable when I run it on my tablet.

  • Is this a known bug?

  • How can I get it to stop shaking?
bemeyer
  • 6,154
  • 4
  • 36
  • 86
hasherr
  • 669
  • 3
  • 14
  • 28
  • Show us how you move your `playerGhost`. If this isnt fluent your font is also shaking. Maybe interpolate the position of the score so the shaking isn't that hard – bemeyer Mar 09 '14 at 10:25

3 Answers3

9

Call scorefont.setUseIntegerPositions(false); so it won't round the font's position to the nearest integer. You will also probably want to set the font's min filtering to Linear or MipmapLinearNearest, and max filtering to Linear.

The reason for the default behavior is that the default configuration is for text that is pixel perfect, for a viewport set with units equal to the size of a pixel. If your viewport had dimensions exactly the same as the screen's pixel dimensions, this configuration would help keep text from looking slightly blurry.

Tenfour04
  • 83,111
  • 11
  • 94
  • 154
3

It could actually be the fact that you're scaling your font.

I had this problem and it's quite complex to understand (and also to fix).

Basically, when you scale fonts, BitmapFont changes the values inside the BitmapFontData by dividing/multiplying. If you do a lot of scaling, with a lot of different values (or an unlucky combination of values), it can introduce rounding errors which can cause flickering around the edges of the font.

The solution I implemented in the end was to write a Fontholder which stores all of the original BitmapFontData values. I then reset the font data to those original values at the beginning of every frame (i.e. start of render() method).

Here's the code...

package com.bigcustard.blurp.core;

import com.badlogic.gdx.graphics.g2d.*;

public class FontHolder {


    private BitmapFont font;
    private final float lineHeight;
    private final float spaceWidth;
    private final float xHeight;
    private final float capHeight;
    private final float ascent;
    private final float descent;
    private final float down;
    private final float scaleX;
    private final float scaleY;

    public FontHolder(BitmapFont font) {

        this.font = font;

        BitmapFont.BitmapFontData data = font.getData();
        this.lineHeight = data.lineHeight;
        this.spaceWidth = data.spaceWidth;
        this.xHeight = data.xHeight;
        this.capHeight = data.capHeight;
        this.ascent = data.ascent;
        this.descent = data.descent;
        this.down = data.down;
        this.scaleX = data.scaleX;
        this.scaleY = data.scaleY;
    }

    // Call this at start of each frame.
    public void reset() {

        BitmapFont.BitmapFontData data = font.getData();
        data.lineHeight = this.lineHeight;
        data.spaceWidth = this.spaceWidth;
        data.xHeight = this.xHeight;
        data.capHeight = this.capHeight;
        data.ascent = this.ascent;
        data.descent = this.descent;
        data.down = this.down;
        data.scaleX = this.scaleX;
        data.scaleY = this.scaleY;
    }

    public BitmapFont getFont() {

        return font;
    }
}

I'm not wild about this, as it's slightly hacky, but it's a necessary evil, and will completely and properly solve the issue.

Phil Anderson
  • 3,146
  • 13
  • 24
1

The correct way to handle this would be to use two different cameras, and two different spriteBatches, one for the game itself and one for the UI. You call the update() method on both cameras, and use spriteBatch.setProjectionMatrix(camera.combined); on each batch to render them at the same time each frame.

Zamaroht
  • 150
  • 1
  • 12