Introduction
The first real “snag” I experienced with Phaser was how to use custom fonts.
You can only display fonts that are currently loaded and available to the browser: therefore fonts must be preloaded. Phaser does not do ths for you, so you will require the use of a 3rd party font loader, or have the fonts ready available in the CSS on the page in which your Phaser game resides.
Okay, that gives us a bunch of options - I went with, in my opinion, the simplest.
document.addEventListener('DOMContentLoaded', function() {
const font = new FontFace('ZXSpectrum', "url('/fonts/ZXSpectrum.ttf') format('truetype')");
font.load().then(function(loadedFont) {
document.fonts.add(loadedFont);
.. Phaser code.
}).catch(function(error) {
console.error('Font failed to load:', error);
});
});
Let’s try it out:
document.addEventListener('DOMContentLoaded', function() {
const font = new FontFace('ZXSpectrum', "url('/fonts/ZXSpectrum.ttf') format('truetype')");
font.load().then(function(loadedFont) {
document.fonts.add(loadedFont);
class BaseScene extends Phaser.Scene {
constructor(key) {
super({ key: key });
// Simply because I've made the assets use scale 4 in the disassembly.
this.gameScale = 4;
// Storage for any text which might need altering (e.g. number of
// fish caught).
this.textObjects = {};
}
printAt(text, x, y, fontSize = '32px', color = '#CDC6CD') {
// Set up the text style:
const textStyle = {
fontFamily: 'ZXSpectrum',
fontSize: fontSize,
color: color
};
// Put the onus on the call to store the text object, if it's static
// text - it can just "fire-and-forget".
return this.add.text(
8 * x * this.gameScale,
8 * y * this.gameScale,
text,
textStyle
);
}
}
class SplashScreen extends BaseScene {
constructor() {
super('SplashScreen');
}
create() {
// All static text:
this.printAt(" BOOTY BY JOHN F CAIN ", 2, 4);
this.printAt("CATCH 20 GOLDFISH", 7, 12);
this.printAt("BUT DONT RUN OUT OF AIR", 4, 14);
this.printAt("OR GET TOO CLOSE TO THE BIG FISH", 0, 16);
}
}
const config = {
type: Phaser.AUTO,
width: 1024,
height: 768,
scene: SplashScreen,
backgroundColor: '#000000',
physics: {
default: 'arcade',
arcade: {
debug: false
}
},
scale: {
mode: Phaser.Scale.FIT,
parent: 'gameContainer',
autoCenter: Phaser.Scale.CENTER_BOTH,
zoom: 0.5
}
};
const game = new Phaser.Game(config);
}).catch(function(error) {
console.error('Font failed to load:', error);
});
});
For non-static text, the only one we have is for the number of collected fish. As it updates, we need to store a reference to it - this is simple though:
// Note; we use a label on this text as it needs to be updated.
this.textObjects['fish-count'] = this.printAt("0", 6, 22, "32px", "#000000");
And (sneak preview), the goldfish collection handler updates this text object directly:
// Updates the fish caught counter on the screen. Note; when the count is
// above 10, we move the horizontal position one digit left to keep the
// unit aligned.
this.textObjects['fish-count'].setText(this.data.get('fishCaught'));
this.textObjects['fish-count'].setPosition((this.data.get('fishCaught') >= 10 ? 5 : 6) * 8 * this.gameScale, 22 * 8 * this.gameScale);
That looks spot on to me!