Подтвердить что ты не робот

Как нарисовать гладкий текст в libgdx?

Я пытаюсь нарисовать простой текст в моей игре для Android на libgdx, но он выглядит острый. Как сделать текст гладким в разных разрешениях? Мой код:

private BitmapFont font;

font = new BitmapFont();

font.scale((ppuX*0.02f));

font.draw(spb, "Score:", width/2-ppuX*2f, height-0.5f*ppuY);
4b9b3361

Ответ 1

Одно из решений - использовать расширение FreeType для libgdx, как описано здесь. Это позволяет вам генерировать растровый шрифт "на лету" с помощью шрифта .ttf. Обычно вы делаете это во время запуска, как только вы узнаете целевое разрешение.

Вот пример:

int viewportHeight;
BitmapFont titleFont;
BitmapFont textFont;

private void createFonts() {
    FileHandle fontFile = Gdx.files.internal("data/Roboto-Bold.ttf");
    FreeTypeFontGenerator generator = new FreeTypeFontGenerator(fontFile);
    FreeTypeFontParameter parameter = new FreeTypeFontParameter();
    parameter.size = 12;
    textFont = generator.generateFont(parameter);
    parameter.size = 24;
    titleFont = generator.generateFont(parameter);
    generator.dispose();
}

Ответ 2

font.getRegion().getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);

Это получает текстуру, используемую в BitmapFont, и изменяет ее фильтрацию на билинейную, что позволяет получить более высокое качество изображения, в то время как увеличение и уменьшение его при стоимости немного медленнее (разница обычно не заметна) рендеринг графического процессора.

Ответ 3

Вы должны определенно быстро просмотреть пользовательские шейдеры шрифтов и/или шрифты DistanceField. Их легко понять и легко реализовать:

https://code.google.com/p/libgdx/wiki/DistanceFieldFonts

DistanceFieldFonts остаются гладкими, даже если вы их масштабируете:

enter image description here

Ответ 4

  • Создайте файл .fnt, используя hiero, который предоставляется веб-сайтом libgdx.
  • Установите размер шрифта на 150; он создаст файл .fnt и файл .png.
  • Скопируйте оба файла в папку с вашими ресурсами.
  • Теперь объявим шрифт:

    BitmapFont font;
    
  • Теперь в методе создания:

    font = new BitmapFont(Gdx.files.internal("data/100.fnt"), false); // 100 is the font name you can give your font any name
    
  • В рендере:

    font.setscale(.2f);
    
    font.draw(batch, "whatever you want to write", x,y);
    

Ответ 5

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

Это подход, который я использую: построение всего для маленького экрана (480 x 320), и когда вы открываете его с большим разрешением, я загружаю BitmapFont с более высоким размером и применяю и инвертирующую шкалу к той, которая Libgdx позже сделает это автоматически.

Вот пример, чтобы сделать вещи более ясными:

    public static float SCALE;
    public static final int VIRTUAL_WIDTH = 320;
    public static final int VIRTUAL_HEIGHT = 480;


    public void loadFont(){

     // how much bigger is the real device screen, compared to the defined viewport
     Screen.SCALE = 1.0f * Gdx.graphics.getWidth() / Screen.VIRTUAL_WIDTH ;

     // prevents unwanted downscale on devices with resolution SMALLER than 320x480
     if (Screen.SCALE<1)
        Screen.SCALE = 1;

     FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("data/Roboto-Regular.ttf"));

     // 12 is the size i want to give for the font on all devices
     // bigger font textures = better results
     labelFont = generator.generateFont((int) (12 * SCALE));

     // aplly the inverse scale of what Libgdx will do at runtime
     labelFont.setScale((float) (1.0 / SCALE));
     // the resulting font scale is: 1.0 / SCALE * SCALE = 1

     //Apply Linear filtering; best choice to keep everything looking sharp
     labelFont.getRegion().getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
}

Ответ 6

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

Этот пост в блоге посвящен таким проблемам

Ответ 7

Со многими устаревшими обновлениями после обновления это работает для меня:

public void regenerateFonts(OrthographicCamera cam, Game game) {
    int size = 18;

    if (cam != null && game != null) {
        // camera and game are provided, recalculate sizes
        float ratioX = cam.viewportWidth / game.getW();
        float ratioY = cam.viewportHeight / game.getH();
        System.out.println("Ratio: [" + ratioX + ":" + ratioY + "]");

        size *= ratioY;
    }

    // font parameters for this size
    FreeTypeFontParameter params = new FreeTypeFontParameter();
    params.flip = true; // if your cam is flipped
    params.characters = LETTERS; // your String containing all letters you need
    params.size = size;
    params.magFilter = TextureFilter.Linear; // used for resizing quality
    params.minFilter = TextureFilter.Linear; // also

    // Lato Light generator
    FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/Lato-Light.ttf"));

    // make the font
    fontLatoLight = generator.generateFont(params);
    generator.dispose(); // dispose to avoid memory leaks
}

И когда вы хотите отобразить его на экране:

// text rendering
fontLatoLight.setColor(Color.WHITE); // set color here (has other overloads too)
fontLatoLight.draw(batch, "Hello World!", xCoord, yCoord);

Ответ 8

private BitmapFont font;

font = new BitmapFont();

font.scale((ppuX*0.02f));

font.draw(spb, "Score:", width/2-ppuX*2f, height-0.5f*ppuY);

    Check out [this](http://www.badlogicgames.com/wordpress/?p=2300) blog post.

??? Это просто объясняет, как использовать метод .scale(), который, как я утверждаю, устарел в текущей версии.

Ответ 9

Мое решение для гладкого текста с Libgdx

Я использую BitmapFont, и я генерирую 3 разных размера одинаковых шрифтов с помощью инструмента Hiero пример Arial 16, Arial 32, Arial 64

Я помещал их в свой файл активов и использовал (load) только один из них, зависящий от размера экрана

if(Gdx.graphics.getWidth() < (480*3)/2)
        {
            textGametFont = BitmapFont(Gdx.files.internal(nameFont+16+".fnt"),
                    Gdx.files.internal(nameFont+16+".png"), false);
        }else
        {
            if(Gdx.graphics.getWidth() < (3*920)/2)
            {

                textGametFont = new BitmapFont(Gdx.files.internal(nameFont+32+".fnt"),
                        Gdx.files.internal(nameFont+32+".png"), false);
            }else
            {
                textGametFont = new BitmapFont(Gdx.files.internal(nameFont+64+".fnt"),
                        Gdx.files.internal(nameFont+64+".png"), false);
            }
        }

то я использую эту строку кода для более высокого качества результата вниз и вверх. Масштабирование

textGametFont.getRegion().getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);

масштабируйте изображение

для обработки размера шрифта для всех типов разрешения устройства я использую эти две функции

public static float xTrans(float x)
{
    return x*Gdx.graphics.width/(YourModel.SCREEN_WIDTH);
}

public static float yTrans(float y)
{
    return y*Gdx.graphics.height/YourModel.SCREEN_Height;
}

разрешение экрана модели, которое я использую,

SCREEN_WIDTH = 480

SCREEN_HEIGHT = 320

Установите масштаб шрифта

textGametFont.setScale((xtrans(yourScale)+ ytrans(yourScale))/2f);

и, наконец, нарисуйте текст

textGametFont.draw(batch, "WINNER !!", xTrans(250), yTrans(236));

Надеюсь, это было понятно и полезно!!!