2

我有一个 BitmapFont,它在玩家以恒定速率在屏幕上移动时显示他的分数。因为播放器总是在移动,所以我必须重新计算每帧在什么位置绘制字体。我使用此代码。

    scoreFont.setScale(4f, 4f);
    scoreFont.draw(batch, "" + scoreToShow, playerGhost.pos.x + 100f, 600f);
    playerGhost.render(batch);
  • 问题?字体不会停止抖动。它只有几个像素的振动,但有点明显。当我在平板电脑上运行它时,它会更加明显。

  • 这是一个已知的错误?

  • 我怎样才能让它停止摇晃?
4

3 回答 3

8

调用scorefont.setUseIntegerPositions(false);它不会将字体的位置四舍五入到最接近的整数。您可能还希望将字体的最小过滤设置为线性或 MipmapLinearNearest,并将最大过滤设置为线性。

默认行为的原因是默认配置是针对像素完美的文本,针对具有等于像素大小的单位设置的视口。如果您的视口的尺寸与屏幕的像素尺寸完全相同,则此配置将有助于防止文本看起来略微模糊。

于 2014-03-09T19:51:14.337 回答
3

实际上可能是您正在缩放字体。

我遇到了这个问题,理解(并且修复)非常复杂。

基本上,当您缩放字体时,BitmapFont 通过除/乘来更改 BitmapFontData 中的值。如果您使用大量不同的值(或值的不幸组合)进行大量缩放,则可能会引入舍入错误,从而导致字体边缘闪烁。

我最终实现的解决方案是编写一个 Fontholder 来存储所有原始 BitmapFontData 值。然后我将字体数据重置为每一帧开始时的那些原始值(即 render() 方法的开始)。

这是代码...

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;
    }
}

我对此并不疯狂,因为它有点hacky,但它是必要的邪恶,并且会完全正确地解决问题。

于 2015-05-08T10:05:54.250 回答
1

处理这个问题的正确方法是使用两个不同的相机和两个不同的 spriteBatch,一个用于游戏本身,一个用于 UI。update()您在两台相机上调用该方法,并spriteBatch.setProjectionMatrix(camera.combined);在每个批次上使用以在每帧同时渲染它们。

于 2014-12-21T02:53:57.590 回答