Introduction

Very often I need to display some information for player in GUI in my games. It is usually composed of some text and icon. And it also often takes some time to fine tune positioning of text and icon. Things get complicated if part of it can change width like number on following image:

Then, if you update number, you also have to update position of icon. Making some longer text, like the one on image bellow, with small images inside of it, is tedious work and usually needs lot of code.

Solution

Fortunately, solution is easy. We can add images as special characters into font and then print whole text, including images, in one call in code.

Let's say you have font called "Font" and atlas called "Game". Font is made of texture with characters and xml metadata file. It can be font made with Littera or any other font tool. Atlas is standard atlas with your game images.

After these are loaded in your preload function - for example like this:

Next we get reference to loaded font xml data and also reference to capital "A" character. Reason for this is, that we will center added images on the same level as center of "A" is.

letfontData=font.font;letcharA=fontData.chars[65];

Now, in my case, I have 7 gem images in atlas with names Gem1 ... Gem7. I will add them as special characters. First, I have to choose character code for them. Here I chose 5000 for Gem1, 5001 for Gem2 ...

First, we get Phaser.Frame from atlas, so we will have access to position and dimensions of image within atlas. Next, we add new object with all font metadata to current font characters data at position of character code we chose before. For yOffset we are doing small calculation to center added images relative to "A" - we want center of A and added images on the same level. xOffset is 1 and it says, that there will be 1 pixel space after previous character. xAdvance then says how much has font renderer step to draw next character. We set this to width + 2 (= xOffset + width + 1). On last line, we are setting texture property. Here you may get error - just head to phaser.d.ts and change BMFontChar interface to use PIXI.Texture instead of PIXI.BaseTexture.

To include gems we make string from character codes with call to String.fromCharCode(). You should see this on screen:

Draw calls

While everything works, there is small issue you should be aware of. As our font images and gem images are in different textures, there can be more draw calls. In above case there are four draw calls to draw this single piece of text.

Fortunately, there is also solution for this. Merge your font into atlas as described in one of previous tutorials. Code changes only very little: