Slick2d Loading font images from glyphs

Hello, I am currently building a game using slick2D. It’s going great so far, but I’ve hit a snag. I can’t seem extract images from a .ttf or .fnt file. What I mean is I can’t seem to get a glyph’s image from a font file.

Given the way that my game engine is built, I never want to draw strings directly from the render() method. My game works by creating displayable objects containing Slick’s built in Image class and putting those objects into containers, then finally, displaying the container. This simplifies the act of treating a group of objects as one. I only mention this because I’ve seen other people draw strings from the render methods directly onto the screen. I want to avoid using this method of drawing text, you see.

Is there any way, in Slick2D, to easily get a glyph’s image from a .ttf or .fnt file? I see that there is a Glyph class which supplies an image for a particular glyph, but found that it requires a TON of information in order to instantiate it.

If I can’t find a way to make this work, I may have to create a .png map of characters myself and read from that file. This is also something I would like to avoid… Any thoughts?

What I walways do is use AngelCodeFont class. Take whatever font you want, open it in BMFont play with the parameters and export. The program will export a png/tga file and a fnt file. And then in java:



//define image
private Image img;
//define angecodefont
public static AngelCodeFont font;

//init method of the main class
public void init(GameContainer gc){

//load image (file location,flip?,filter)
img= new Image("data/fonts/font.png",false,Image.FILTER_NEAREST);

//load font(fnt location,image)
font= new AngelCodeFont("data/fonts/font.fnt",img); 

}

Once you learn to use it is very easy and fast to use it! And for render it just this:



public void render(Graphics g){

font.render(10,10,"Hello World!");

}

And so…where do you want to render the string if not from the render method?o.O

Take a look at the javadoc too: http://slick.cokeandcode.com/javadoc/org/newdawn/slick/AngelCodeFont.html

Hope it helps :slight_smile:

I appreciate your input. So by the post above, if you use AngelCodeFont, specify an image, and draw a string, it will draw to that image? Also, maybe I should clarify. I extended the BasicGame class so that it only paints a heirarchy of images. It really simplifies trying to find a certain visual effect. In the end, the text would be rendered to the screen, but it would not be done directly.

I’d say your design is flawed if you can’t simply call “font.draw()” in your game. For example; instead of relying on a list of Image objects, you should write your own Entity or Renderable interface with a draw() method. Subclasses (e.g. ImageEntity, TextEntity) would simply override the draw method to implement the given functionality.

Also keep in mind that it’s generally wise to “batch” images that share the same texture (i.e. sprite sheets, bitmap fonts) to improve performance. So, instead of making each of your sprites in the same sheet call Image.draw(), you should look into using startUse/endUse/drawEmbedded.

For bitmap fonts, look into TWL’s Font Tool (save as text) or Hiero. Then you simply use AngelCodeFont to load and render the text.

I DO plan to do something along the lines of “font.draw()” like you suggested, but until I get to that point, I need to first figure out how to get individual glyph images from fonts…

Still not sure why you need individual images for this, but anyways, I pushed an enhancement to AngelCodeFont some time ago that lets you get the individual Glyph for a character. There is an example in FontTest that uses “custom rendering” by grabbing each sub-image and rendering it within a startUse/endUse block. Grab the new code from the slick dev branch.

Two things to keep in mind: The glyph image is a sub-image – i.e. each glyph points to the same PNG texture. Also ensure you use startUse/endUse otherwise your performance will take a hit.

Ah, okay then. The reason I insist on rendering in this fashion is because I come from a Flash background where every object that is displayed is considered a symbol rather than bitmap data that can be painted on. Transitioning can get a bit confusing…

You can do the same thing using interfaces in Java.

public interface Sprite {
    public void draw(Graphics g, int x, int y);
}
public class Label implements Sprite {
    private String str;

    public Label(String str) {
        this.str = str;
    }

    public void draw(Graphics g, int x, int y) {
        g.drawString(str, x, y);
    }
}

Apply the same pattern to Image, Animation, etc.