37

I've been having a lot of trouble Googling how to draw simple 2D text with Libgdx. Here is the code that I've put together so far:

SpriteBatch spriteBatch;
BitmapFont font;
CharSequence str = "Hello World!";
spriteBatch = new SpriteBatch();
font = new BitmapFont();

spriteBatch.begin();
font.draw(spriteBatch, str, 10, 10);
spriteBatch.end();

The code does draw the Hello World string, however, it messes up all my other drawings. They are there, only brutally mutilated, and move and all that. I've tried Gdx.gl11.glPushMatrix() and Gdx.gl11.glPopMatrix() around just about every subset of statements.

I've narrowed the mutilated drawings down to the font.draw() call, if that's taken out, everything works fine (but of course there is no text then).

Ziem
  • 6,579
  • 8
  • 53
  • 86
Asgeir
  • 727
  • 3
  • 9
  • 20

4 Answers4

28

I don't see much reason of creating separate batch for text drawing. Using gdxVersion = '1.4.1' (built with gradle in Android Studio) that code draws text successfully:

BitmapFont font = new BitmapFont(); //or use alex answer to use custom font

public void render( float dt )
  {
    batch.setProjectionMatrix(camera.combined); //or your matrix to draw GAME WORLD, not UI

    batch.begin();

    //draw background, objects, etc.
    for( View view: views )
    {
      view.draw(batch, dt);
    }

    font.draw(batch, "Hello World!", 10, 10);

    batch.end();
  }

Note, that here you draw in game world coordinates, so if your character moves (in platformer, for example), than text will move too. If you want to see text, that it will be fixed on screen, something like Label/TextField or how it is called in different UI frameworks, than I recommend to use Stage (and TextArea for text), see for example on how to use Stage here: http://www.toxsickproductions.com/libgdx/libgdx-basics-create-a-simple-menu/

Deepscorn
  • 822
  • 10
  • 22
15

When I created the Bitmap font it was like this:

font = new BitmapFont(Gdx.files.internal("Calibri.fnt"),Gdx.files.internal("Calibri.png"),false);

try this by downloading some font file(while downloading a font please check if .fnt file and .png file is included for the same)

alex
  • 358
  • 3
  • 14
  • 5
    It makes no difference. Instancing it with ´new BitmapFont()´ will use the default embedded font. – Gustavo Maciel Jan 07 '13 at 01:17
  • 1
    And BitmapFont alone doesn't render. BitmapFont is the config for how it renders the text. The batch draws the text using BitmapFont and a String (the text to draw) – Zoe Jul 16 '17 at 17:18
8

To create a .fnt file, use hiero which is provided by LibGDX's website.

Set the size of font 150, it will create a .fnt file and a .png file. Copy both files in your assets folder.

To declare the font:

BitmapFont font;

To load the font: (In create method)

font = new BitmapFont(Gdx.files.internal("data/rayanfont.fnt"), false);
//rayanfont is the font name

To render:

batch.begin();
font.setScale(.2f);
font.draw(batch, "hello", x,y);
batch.end();

This will work smoothly.

Winter
  • 3,894
  • 7
  • 24
  • 56
sandeep kundliya
  • 963
  • 8
  • 13
  • 3
    For those who are using ```.setScale();``` and it shows an error that means that you have a newer version of LibGDX. Use instead ```font.getData().setScale(0.2f);``` – Joseph Attia May 17 '21 at 23:04
5

Try to call multiple batch.begin() and batch.end():

CharSequence str = "Hello World!";
spriteBatch = new SpriteBatch();
font = new BitmapFont();

spriteBatch.begin();
font.draw(spriteBatch, str, 10, 10);
spriteBatch.end();
spriteBatch.begin();
//draw your other sprites here
spriteBatch.draw(...);
spriteBatch.end();

or just use a different instance of SpriteBatch

user1708101
  • 69
  • 1
  • 2
  • 4
  • This is suboptimal because it will lead to excessive flushing (on `end()`) if you need to render lots of text at different times. – EntangledLoops Jan 10 '21 at 20:30