J'essaie de dessiner du texte simple dans mon Android sur libgdx, mais il est net. 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);
Une solution consiste à utiliser l'extension FreeType de libgdx, comme décrit ici . Cela vous permet de générer une police bitmap à la volée à partir d'une police .ttf. Généralement, vous le feriez au moment du 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();
}
font.getRegion().getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
Cela obtient la texture utilisée dans un BitmapFont et change son filtrage en bilinéaire, permettant une qualité d'image résultante plus élevée tout en la faisant monter et en descendant à l'échelle au prix d'un rendu GPU légèrement plus lent (la différence n'est généralement pas perceptible).
Vous devriez certainement avoir un aperçu rapide des shaders de polices personnalisées et/ou des polices DistanceField. Ils sont faciles à comprendre et à mettre en œuvre de la même manière:
https://github.com/libgdx/libgdx/wiki/Distance-field-fonts
Les polices DistanceField restent fluides, même lorsque vous les augmentez:
Déclarez maintenant 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
En rendu:
font.setscale(.2f);
font.draw(batch, "whatever you want to write", x,y);
En général, vous n'obtenez pas de texte net parce que vous concevez votre jeu pour une certaine résolution et lorsque vous passez à un autre appareil, Libgdx met tout à l'échelle pour correspondre à la nouvelle résolution. Même avec un filtrage linéaire, la mise à l'échelle est mauvaise sur le texte car les coins arrondis sont facilement déformés. Dans un monde parfait, vous créeriez le contenu dynamiquement lors de l'exécution en fonction du nombre de pixels disponibles et aucune échelle automatique ne serait utilisée.
Voici l'approche que j'utilise: tout construire pour un petit écran (480 x 320), et lorsque vous l'ouvrez sur une résolution plus grande, je charge le BitmapFont avec une taille plus élevée et applique et une échelle inverse à celle que Libgdx plus tard faire 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);
}
Les polices bitmap sont des textures et si vous souhaitez rendre les textures plus petites plus lisses lorsque vous les redimensionnez à des tailles plus grandes, vous devez vous assurer que vous utilisez le bon filtre de texture.
Avec beaucoup de choses obsolètes après la mise à jour, voici 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 le rendre à l'écran:
// text rendering
fontLatoLight.setColor(Color.WHITE); // set color here (has other overloads too)
fontLatoLight.draw(batch, "Hello World!", xCoord, yCoord);
Ma solution pour un texte fluide avec Libgdx
J'utilise BitmapFont et je génère 3 polices de même taille différentes à l'aide de l'outil Hiero, exemple Arial 16, Arial 32, Arial 64
Je les mets dans mon fichier d'actifs et n'utilise (charge) qu'un seul d'entre eux en fonction de 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);
}
}
puis j'utilise cette ligne de code pour une qualité de résultat supérieure de mise à l'échelle vers le haut et vers le bas
textGametFont.getRegion().getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
redimensionner l'image
pour gérer la taille de la police pour tout type de résolution d'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 du modèle que j'utilise est
SCREEN_WIDTH = 480
SCREEN_HEIGHT = 320
Réglez l'échelle sur la police
textGametFont.setScale((xtrans(yourScale)+ ytrans(yourScale))/2f);
et enfin dessiner votre texte
textGametFont.draw(batch, "WINNER !!", xTrans(250), yTrans(236));
J'espère que c'était clair et utile !!!
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.
??? Cela explique simplement comment utiliser la méthode .scale () que je déclare être obsolète dans la version actuelle.
Dans scene2d, si vous voulez appliquer l'anticrénelage à 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);
Ceci 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 le fichier i.json, vérifiez BitmapFont et Label $ LabelStyle section:
"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",
}
},