1
\$\begingroup\$

I have big problem with drawing font. My virtual world is 20x15 meters (viewport and camera too). I use FreeTypeFontGenerator. But something is wrong because for example if I have font 40px (40px = 1 meter) my font is very huge. I tried scaling but effect is bad. I read somewhere that using second SpriteBatch will solve problem? or maybe someone have different idea?

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

You can use different view ports to make sure the font doesn't get to streched out.

For example, if your viewport is 20x15 then a BitmapFont rendered at font size 12 (for example) will look very big, but you can let the view port used when rendering the text be a special one, that's been set to a larger size.

Example rendering text in the 20x15 view port size: enter image description here

But if the viewport for the text is scaled up: enter image description here

A code example of how to achieve that could look something like this;

package com.bornander.androidstudiosandbox;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;

public class MyAndroidStudioSandboxGame extends Game {
    private SpriteBatch batch;
    private OrthographicCamera camera;
    private OrthographicCamera textCamera;
    private BitmapFont font;

    @Override
    public void create () {
        batch = new SpriteBatch();

        // I am not setting my viewport to be 20x15, but 20x<whatever make sense for the aspect ratio to be maintained>
        float aspectRatio = (float)Gdx.graphics.getHeight() / (float)Gdx.graphics.getWidth();
        float viewPortWidth = 20;
        float viewPortHeight = viewPortWidth * aspectRatio;

        float cameraViewPortWidth = 1024; // Set the size of the viewport for the text to something big
        float cameraViewPortHeight = cameraViewPortWidth * aspectRatio;

        camera = new OrthographicCamera(viewPortWidth, viewPortHeight);
        textCamera = new OrthographicCamera(cameraViewPortWidth, cameraViewPortHeight);

        font = buildFont("Arial.ttf", 8, "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890\"!`?'.,;:()[]{}<>|/@\\^$-%+=#_&~*");
    }

    private static BitmapFont buildFont(String filename, int size, String characters) {
        FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal(filename));
        FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter();
        parameter.size = size;
        parameter.characters = characters;
        parameter.kerning = true;
        parameter.magFilter = Texture.TextureFilter.Linear;
        parameter.minFilter = Texture.TextureFilter.Linear;
        BitmapFont font = generator.generateFont(parameter);
        font.getData().markupEnabled = true;
        generator.dispose();
        return font;
    }

    @Override
    public void render () {
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        camera.update();
        textCamera.update();

        batch.begin();
        batch.setProjectionMatrix(camera.combined);
        // Render you game here using the "game" camera

        // Here we change the projection, and render the text
        batch.setProjectionMatrix(textCamera.combined);
        font.draw(batch, "ABC", 0 ,0);

        batch.end();
    }
}

Note that the actual size of the window or display that is used to show the game also has some bearing on the result.

\$\endgroup\$
8
  • \$\begingroup\$ I did it, thank you :) but I have two other problems. First: I cant change Font color for custom color. I tried make new Color color = new Color() but my Font is still white. Second: can I change coordinates of my camera? now when I'm drawing in (0,0) my text is in the center of the screen but I want to have (0,0) in the lower left corner. \$\endgroup\$
    – Land93
    Nov 24, 2016 at 15:55
  • 1
    \$\begingroup\$ @Land93 You're better off asking those questions as proper question instead of as comments here, it will increase the likelyhood of you getting an answer. \$\endgroup\$
    – bornander
    Nov 24, 2016 at 18:16
  • \$\begingroup\$ An even simpler solution would be to call batch.setProjectionMatrix(null) before rendering the text instead of creating a new camera or viewport for the text. \$\endgroup\$
    – Charanor
    Jan 11, 2017 at 8:43
  • \$\begingroup\$ use different view ports, it's ok. but if you want to move it with the enemy X and Y, how will you do that? @bornander \$\endgroup\$
    – Nimitack
    Jun 18, 2017 at 18:57
  • \$\begingroup\$ @rosa Take the enemy's​ position and project it to screen space using the game Camera, then un-project that position to the HUD Camera space. Render the text at that position using the HUD Camera. \$\endgroup\$
    – bornander
    Jun 18, 2017 at 23:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .