LibGDX BitmapFont не перестанет дрожать

У меня есть BitmapFont, который отображает счет игрока, когда он перемещается по экрану с постоянной скоростью. Поскольку игрок всегда движется, я должен пересчитать, в какой позиции я рисую шрифт в каждом кадре. Я использую этот код.

    scoreFont.setScale(4f, 4f);
    scoreFont.draw(batch, "" + scoreToShow, playerGhost.pos.x + 100f, 600f);
    playerGhost.render(batch);
  • Эта проблема? Шрифт не перестанет дрожать. Это всего лишь несколько пикселей вибрации, но это немного заметно. Это более заметно, когда я запускаю его на своем планшете.

  • Это известная ошибка?

  • Как я могу заставить его перестать трястись?

3 ответа

Вызов scorefont.setUseIntegerPositions(false); поэтому он не будет округлять позицию шрифта до ближайшего целого числа. Возможно, вы также захотите установить минимальную фильтрацию шрифта на Linear или MipmapLinearNearest, а максимальную фильтрацию на Linear.

Причиной поведения по умолчанию является то, что конфигурация по умолчанию предназначена для текста с идеальным разрешением в пикселях, для области просмотра, установленной с единицами измерения, равными размеру пикселя. Если ваш видовой экран имеет размеры, точно совпадающие с размерами экрана в пикселях, эта конфигурация поможет сохранить слегка размытый текст.

Это может быть факт, что вы масштабируете свой шрифт.

У меня была эта проблема, и это довольно сложно понять (и также исправить).

В основном, когда вы масштабируете шрифты, 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;
    }
}

Я не в восторге от этого, так как он немного хакерский, но это неизбежное зло, и он полностью и правильно решит проблему.

Правильный способ справиться с этим - использовать две разные камеры и две разные spriteBatches, одну для самой игры и одну для пользовательского интерфейса. Вы называете update() метод на обеих камерах, и использовать spriteBatch.setProjectionMatrix(camera.combined); на каждой партии, чтобы сделать их одновременно каждый кадр.

Другие вопросы по тегам