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

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

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

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

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

person hasherr    schedule 08.03.2014    source источник
comment
Покажите нам, как вы двигаете playerGhost. Если это не бегло, ваш шрифт также дрожит. Может быть, интерполировать положение партитуры, чтобы тряска не была такой сильной.   -  person BennX    schedule 09.03.2014


Ответы (3)


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

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

person Tenfour04    schedule 09.03.2014

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

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

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

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

person Phil Anderson    schedule 08.05.2015
comment
Христос живой, это много. Я давно отказался от этого вопроса, но могу сказать, что это правда. - person hasherr; 08.05.2015
comment
(2018) — похоже, spaceWidth переименован в spaceXadvance. - person VILLAIN bryan; 02.08.2018

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

person Zamaroht    schedule 21.12.2014