Comment dessiner du texte lisse dans libgdx?

j'essaie de dessiner du texte simple dans mon jeu android sur libgdx, mais ça a l'air pointu. Comment rendre le texte lisse dans différentes résolutions? Mon Code:

private BitmapFont font;

font = new BitmapFont();

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

font.draw(spb, "Score:", width/2-ppuX*2f, height-0.5f*ppuY);
32
demandé sur StarsSky 2013-02-03 21:14:36

10 réponses

Une solution consiste à utiliser la FreeType extension de libgdx, tel que décrit ici. Cela permet de générer une police bitmap à la volée à partir d'une .police ttf. Généralement, vous le feriez au démarrage Une fois que vous connaissez la résolution cible.

Voici un exemple:

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();
}
28
répondu Rod Hyde 2014-12-15 22:00:48
font.getRegion().getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);

cela obtient la texture utilisée dans un BitmapFont et change son filtrage à bilinear, permettant une meilleure qualité d'image résultante tout en haut - et en bas de l'échelle au coût de rendu GPU légèrement plus lent (la différence n'est généralement pas perceptible).

49
répondu bluepuppy 2014-12-07 14:31:22

vous devriez avoir un coup d'oeil rapide sur les polices de caractères personnalisées et/ou DistanceField-Fonts. Ils sont faciles à comprendre et tout aussi faciles à mettre en œuvre:

https://github.com/libgdx/libgdx/wiki/Distance-field-fonts

DistanceFieldFonts rester lisse, même lorsque vous leur haut de gamme:

enter image description here

21
répondu TheWhiteLlama 2018-08-13 09:25:08
  • Créer un .fichier fnt utilisant hiero qui est fourni par le site Web de libgdx.
  • Réglez la taille de la police à 150; elle créera un .dossier de la TPN et A.fichier png.
  • Copiez les deux fichiers dans votre dossier actif.
  • maintenant, déclarez la police:

    BitmapFont font;
    
  • maintenant dans la méthode create:

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

    font.setscale(.2f);
    
    font.draw(batch, "whatever you want to write", x,y);
    
12
répondu sandeep kundliya 2015-04-26 01:09:10

en général, vous ne recevez pas de texte pointu parce que vous concevez votre jeu pour une certaine résolution et quand vous vous déplacez vers un périphérique différent, Libgdx met tout à l'échelle pour correspondre à la nouvelle résolution. Même avec l'échelle de filtrage linéaire est mauvais sur le texte parce que les coins ronds sont facilement déformés. Dans un monde parfait, vous créeriez le contenu dynamiquement à l'exécution en fonction du nombre de pixels disponibles pour vous et pas une seule échelle automatique serait utilisée.

C'est le approche que j'utilise: tout construire pour petit écran (480 x 320), et quand vous l'ouvrez sur une plus grande résolution, je charge le BitmapFont avec une taille plus élevée et applique et inverse l'échelle à celle que Libgdx fera plus tard automatiquement.

voici un exemple pour clarifier les choses:

    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
répondu sheitan 2014-11-11 13:28:59

les polices Bitmap sont des textures et si vous voulez que les petites textures paraissent plus lisses lorsque vous les redimensionnez en plus grandes tailles, vous devez vous assurer d'utiliser le bon filtre de texture.

Ce blog traite de ces questions

2
répondu Glogo 2013-02-06 17:57:56

beaucoup de choses obsolète après la mise à jour, c'est ce qui fonctionne pour moi:

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
}

Et quand vous voulez vous rendre sur l'écran:

// text rendering
fontLatoLight.setColor(Color.WHITE); // set color here (has other overloads too)
fontLatoLight.draw(batch, "Hello World!", xCoord, yCoord);
2
répondu milosmns 2014-08-09 23:27:50
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.

??? Ceci explique juste comment utiliser le .scale() méthode qui je suis en déclarant est obsolète dans la version actuelle.

1
répondu shajeer puzhakkal 2015-06-23 10:33:23

Ma Solution pour le bon texte avec Libgdx

J'utilise BitmapFont et je génère 3 polices différentes de même taille en utilisant L'outil Hiero exemple Arial 16, Arial 32, Arial 64

je les ai mis dans mon fichier d'actifs et d'utilisation (charge) d'un seul d'entre eux selon la taille de l'écran

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

alors j'utilise cette ligne de code pour qualité de résultat supérieure de haut en bas d'Échelle

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

échelle de l'image

gérer la taille de la police pour tous les types de résolution de l'appareil j'utilise ces deux fonctions

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

la résolution d'écran que j'utilise est

SCREEN_WIDTH = 480

SCREEN_HEIGHT = 320

réglez l'échelle à la police

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

et enfin attirer votre texte

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

J'espère que c'était clair et utile !!!

1
répondu Netero 2015-10-15 18:36:42

scene2d, si vous voulez appliquer antialiasing à toutes vos étiquettes, mettez ceci sur le constructeur de votre premier écran:

skin.getFont("default-font").getRegion().getTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);

C'est le premier écran de mon jeu:

...
public class MainMenuScreen implements Screen {    
    public MainMenuScreen() {
        ...
        skin.getFont("default-font").getRegion().getTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
    }
}

le nom de la police est dans interface utilisateur.json fichier, vérifiez que BitmapFont et Label$LabelStyle l'article:

"com.badlogic.gdx.graphics.g2d.BitmapFont": {
    "default-font": {
      "file": "default.fnt"
    }
  },
"com.badlogic.gdx.scenes.scene2d.ui.Label$LabelStyle": {
    "default": {
      "font": "default-font",
      "fontColor": "white",
    }
  },
0
répondu Andreybeta 2018-06-12 16:42:43