首页 文章

如何在libgdx中绘制流畅的文本?

提问于
浏览
32

我尝试在我的安卓游戏中绘制简单的文字 libgdx ,但它看起来很清晰 . 如何使文本在不同的分辨率下看起来流畅?我的代码:

private BitmapFont font;

font = new BitmapFont();

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

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

10 回答

  • 6

    一种解决方案是使用libgdx的FreeType扩展,如here所述 . 这允许您从.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();
    }
    
  • 21
    font.getRegion().getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
    

    这将获得BitmapFont中使用的纹理并将其过滤更改为双线性,从而允许更高的结果图像质量,同时以略微更慢(差异通常不明显)GPU渲染的成本进行上下缩小 .

  • 2

    您应该快速查看自定义字体着色器和/或DistanceField-Fonts . 它们易于理解,同样易于实现:

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

    DistanceFieldFonts保持平滑,即使你高档它们:

    enter image description here

  • 0
    • 使用libgdx网站提供的hiero创建.fnt文件 .

    • 将字体大小设置为150;它将创建一个.fnt文件和一个.png文件 .

    • 将两个文件复制到资源文件夹中 .

    • 现在声明字体:

    BitmapFont font;
    
    • 现在在create方法中:
    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);
    
  • 1

    一般情况下,由于您正在设计游戏以获得特定分辨率,并且当您移动到其他设备时,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);
    }
    
  • 28

    位图字体是纹理,如果要在将尺寸调整为更大尺寸时使较小纹理看起来更平滑,则需要确保使用正确的纹理滤镜 .

    This blog post deals with such issues

  • 2

    更新后很多东西都被弃用了,这对我有用:

    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);
    
  • 1
    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()方法 .

  • 12

    My Solution for smooth text with Libgdx

    我使用BitmapFont并使用Hiero工具示例Arial 16,Arial 32,Arial 64生成3种不同大小的相同字体

    我把它们放在我的资产文件中,并根据屏幕大小使用(加载)其中一个

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

    希望这是明确和有用的!

  • 49

    scene2d 中,如果要对所有标签应用抗锯齿,请将其放在第一个屏幕的构造函数中:

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

    这是我游戏中的第一个屏幕:

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

    字体名称在 ui.json 文件中,检查BitmapFont和Label $ LabelStyle部分:

    "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",
        }
      },
    

相关问题