Search code examples
libgdxasset-managementbitmap-fonts

Managing Bitmap Font assets in LibGdx


I can load a Bitmap Font just fine with the following code:

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

but I'm trying to implement the AssetManager instead. So I recoded that snippet with the following code:

AssetManager assetManager = new AssetManager();
assetManager.load( "Fonts/MyFont.fnt", BitmapFont.class );
assetManager.load( "Fonts/MyFont.png", Texture.class );
assetManager.finishLoading();
BitmapFont font = assetManager.get( "Fonts/MyFont.fnt" );

If failed of course. The the call to the finishLoading() method returned a message indicating:

Couldn't load dependencies of asset: "Fonts/MyFont.fnt"

Ok. that makes sense, because I didn't do anything with the texture. So how do I pass the texture file as dependency? github.com/libgdx/libgdx/wiki/Managing-your-assets says:

BitmapFontLoader is a good example of an asynchronous loader that also has dependencies that need to be loaded before the actual asset can be loaded (in that case it's the texture storing the glyphs). Again, you can do pretty much anything with this.

Well Duh! I guess they assume, "... if you only knew how!" But, their example doesn't show how - as a matter of fact their example shows pretty much what I've written. So, I'm stumped. All Google seems to be able to find are examples of what to do with TTF fonts, but nothing for regular old Bitmap Fonts.

Does anyone have an example of the solution to this error. Thanks a million!


Solution

  • When you use the AssetManager to load a BitmapFont is uses the BitmapFontLoader class. In the Libgdx api docs is says (api)

    AssetLoader for BitmapFont instances. Loads the font description file (.fnt) asynchronously, loads the Texture containing the glyphs as a dependency.

    The glyphs texture is automatically loaded as a dependency of the font. However, to know which file to load as the texture it checks in the .fnt file for the location of the texture.

    I suspect that the reason that the font loaded successfully without using the AssetManager was because you manually added the Texture of the font as a parameter.

    BitmapFont font= new BitmapFont( 
            Gdx.files.internal( "Fonts/MyFont.fnt" ),
            Gdx.files.internal( "Fonts/MyFont.png" ), // This lets it know what texture to use
            false );
    

    When you used the AssetManager on the other hand it could not find/load the texture dependency. To fix this, open the .fnt file and make sure that the file="something.png" points to your fonts texture glyphs. (It must be the same as the name of the png. In your case file="MyFont.png")

    That hopefully will solve your problem.

    My tried and tested code:

        AssetManager manager = new AssetManager();
        manager.load("fonts/MyFont.fnt", BitmapFont.class);
        manager.finishLoading();
    
        font = manager.get("fonts/MyFont.fnt", BitmapFont.class);
    

    An extract of the MyFont.fnt file:

    info face=font size=54 bold=0 italic=0 charset= unicode= stretchH=100 smooth=1
    aa=1 padding=2,2,2,2 spacing=0,0 outline=0 common lineHeight=50 base=43 scaleW=243
    scaleH=511 pages=1 packed=0
    page id=0 file="MyFont.png"  <-- The important part
    

    Hopefully that will solve your problem!


    Also please note, as I was testing out the AssetManager I noticed that it only loaded when the .fnt was in basic text. When I tried use a .fnt file which used tags (like html) the texture failed to load. I used littera to generate the bitmap font I used for my test.