genjipress

Custom font works oddly with game.add.text

Recommended Posts

I'm using game.add.text to place text on the canvas, and I'm using a TTF font defined in my page's <style> block with the @font-face declaration. The problem is, the font never seems to load the first time around -- it only works after about a second or so.

 

I tried setting the default fonts on the canvas element using CSS, but that doesn't seem to solve the problem.

 

Is there a way to declaratively pre-load TTF fonts for use in a game? The docs talk about loading bitmap fonts but that isn't what I'm trying to do.

Share this post


Link to post
Share on other sites

You just need to make sure that your font is properly loaded before you create your text object, there are several hacks to do that, but first make sure you put your Css before your DOM and your Js.

Share this post


Link to post
Share on other sites

I had this situation with general canvas use (not Phaser specific) and I found a solution that seemed to work for me. If you add the @font-face rule as you did in your CSS, load it before any JS, and a also put an element on the page with one character and the style set to that font, it should load it before it gets to your JS. So, something <div>.</div>, set the div's font to the custom font, and then just absolutely position it off screen somewhere. I don't think you can use display: none; to hide it, because then the font won't load. Give that a try.

Share this post


Link to post
Share on other sites

Jackrugile, I tried that and it doesn't seem to work either. Perhaps if you could post some sample code, I could look at it and try duplicating it on my end?

 

I believe this is what Jackrugile is talking about. This approach worked for me (see my slight tweak in the next post).

 

http://www.html5gamedevs.com/topic/4835-how-to-use-fontsquirrel-with-phaser/?p=30419

Share this post


Link to post
Share on other sites

Just in case anyone else needs this, I use another method to fix the font issues: I simply add a new text in the Boot or Preload State, before any other text is rendered, and set it very small or out of the screen. Every text that comes after that one will have the font loaded.

this.game.add.text(0, 0, "fix", {font:"1px MyCustomFont", fill:"#FFFFFF"});

This way you don't need to add extra HTML elements and CSS styles.

Share this post


Link to post
Share on other sites

Personally I worked around it by loading the fonts in the surrounding HTML page's CSS and when the game starts, delay 2 seconds to allow the font to load before anything displays.  It's a bit of a hack but it works, I've tested it on PC's in a few different locations / connection speeds.  Of course depending how big your TTF file is you might have to delay longer.  I used a simple ZX spectrum style font in my game and it loads quickly, but still I need that 2 seconds delay for it to work straight away.

 

So in my HTML page I have the following in the <head> section.  (In my example I use a CSS3 font-face but could just be a TTF).

    <style type="text/css">                @font-face {            font-family: 'gameFont';            src: url('fonts/zx_spectrum-7-webfont.eot');            src: url('fonts/zx_spectrum-7-webfont.eot?#iefix') format('embedded-opentype'),                                  url('fonts/zx_spectrum-7-webfont.ttf') format('truetype'),                 url('fonts/zx_spectrum-7-webfont.svg#zx_spectrum-7regular') format('svg');            font-weight: normal;            font-style: normal;        } </style>

And then at the top of my javascript I have:

// phaser font styles (use in conjunction with css font face)var fontStyleMain = {    font: "48pt gameFont",    fill: "#ffffff",         shadowOffsetX: 0,    shadowOffsetY: 0,    shadowBlur: 8,    shadowColor: '#000000'};var txtTitle;

And then I can refer to it thus in the preload() function:

// wait a moment to allow CSS and fonts to load    game.time.events.add(2000, function () {               txtTitle = game.add.text(100, 50, "MR. GOGGLES", fontStyleMain);         // ***** the rest of your preload code goes here ***** //    },this);

This then gives a 2000 millisecond (2 sec) delay and the font will be loaded by the time you display anyhing.  You would have to experiment with this number to suit your TTF font.

 

Here's the page if you want to see it working:  http://www.owensouthwood.com/mrgoggles

Share this post


Link to post
Share on other sites

I faced problem like you and did not like solution to wait for N seconds or wait for user input, here is 100% working and proper solution:

var on_device_ready = function() {
  // https://github.com/bramstein/fontfaceobserver  
  var font_calibri = new FontFaceObserver('Calibri');

  Promise.all([font_calibri.load()]).then(function () {
    game = new Phaser.Game(...)
    ...
  });
}
window.onload = on_device_ready;

Within your index.html file you should add

<style>
  @font-face {
    font-family: 'Calibri';
    src: url('assets/font/Calibri-Bold.woff') format('woff'),
    url('assets/font/Calibri-Bold.ttf') format('truetype');
    font-weight: bold;
    font-style: normal;
  }
</style>

It may take some time before you can do everything correctly but I used this method on thousands of old/new mobiles and it works fine

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.