phaser-cli icon indicating copy to clipboard operation
phaser-cli copied to clipboard

Loading XML Bitmap fonts

Open msanatan opened this issue 7 years ago • 8 comments

Hey,

First of all I super love this repo! I'd like some help, how do you import Bitmap fonts? Maybe I'm missing something but I can't seem to import them, for e.g.:

// Just importing a generic, free pixel font
import llpixel3png from '../assets/font/llpixel3.png'
import llpixel3xml from '../assets/font/llpixel3.xml'

And without even loading them in the preload section I get the following errors:

Uncaught Error: Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
| <?xml version="1.0"?>
| <font>
| <info face="LLPixel" size="32" bold="0" italic="0" charset="" unicode="0" stretchH="100" smooth="1" aa="1" padding="1,1,1,1" spacing="-2,-2"  />
/src/assets/font/llpixel3.xml
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
| <?xml version="1.0"?>
| <font>
| <info face="LLPixel" size="32" bold="0" italic="0" charset="" unicode="0" stretchH="100" smooth="1" aa="1" padding="1,1,1,1" spacing="-2,-2"  />

I tried to put the xml extension in the raw and file loaders in the phaser-scripts folder but to no avail. If there's no way to import XML right now, maybe we can include this loader? https://www.npmjs.com/package/xml-loader

msanatan avatar Jun 02 '18 03:06 msanatan

Hey, thanks for reporting the issue! The reason for this problem is because phaser-cli uses file-loader to bundle up all the assets for a game. Unfortunately it's only testing for image files at the moment (as you mentioned) which is a bit of an oversight on my part!

I'm unsure why changing adding xml to the file-loader test didn't work for you, but I'll deploy the changes from the related PR and it should fix it.

If you've already ejected your project from phaser-cli, it should just be a case of updating your webpack dev and prod configs to have the following changes: https://github.com/phaser-cli/phaser-cli/pull/17/files

I'm sure there will be a ton of other file extensions missing at the moment too, a workaround would be to stick your fonts into the static folder, and then load them as a static resource:

Example:

this.load.bitmapFont('llpixel3', '/static/llpixel3.png', '/static/llpixel3.xml')

nerdenough avatar Jun 04 '18 07:06 nerdenough

@phaser-cli/[email protected] has been deployed with the fix. Let me know if that works for you 🙂

nerdenough avatar Jun 04 '18 07:06 nerdenough

Hey, thanks for the quick reply! I've been a bit away this weekend so I'll check it later tonight 🙂. I also added ogg + mp3 to the file loader for music, but I can get to that later after checking the XML. Thanks again! I'll let you know soon

msanatan avatar Jun 06 '18 00:06 msanatan

Hey @nerdenough, unfortunately it still isn't working! I get the following error even if I reference the XML file stored in the static folder as you suggested

Uncaught TypeError: Failed to execute 'createObjectURL' on 'URL': No function was found that matched the signature provided.
    at Function.push../node_modules/phaser/src/loader/File.js.File.createObjectURL (File.js:557)
    at ImageFile.onProcess (ImageFile.js:142)
    at LoaderPlugin.nextFile (LoaderPlugin.js:827)
    at ImageFile.onLoad (File.js:328)

Have you encountered anything similar to this while loading a bitmap font?

Side note, to get music working I added ogg|mp3 to the file-loader configs and then add:

audio: {
  disableWebAudio: true
},

to the game config. The console shows the error below but it plays as expected

Uncaught TypeError: Cannot read property 'emit' of null
    at HTML5AudioFile.onProgress (HTML5AudioFile.js:120)

msanatan avatar Jun 08 '18 04:06 msanatan

Hmm, so here's an example scene that works for me, loading via either bundled or static assets (comment either one out), using @phaser-cli/[email protected]:

import { Scene } from 'phaser'
import atari from '../assets/atari-classic.png'
import atariXml from '../assets/atari-classic.xml'

export default class PlayScene extends Scene {
  constructor () {
    super({ key: 'PlayScene' })
  }

  preload () {
    this.load.bitmapFont('atari-classic', atari, atariXml)
    this.load.bitmapFont('atari-classic', '/static/atari-classic.png', '/static/atari-classic.xml')
  }

  create () {
    this.add.bitmapText(0, 0, 'atari-classic', 'Hello World')
  }
}

What code are you using to load or draw text (if you're able to share)?

Have created a separate issue for the audio.

nerdenough avatar Jun 08 '18 09:06 nerdenough

Hey @nerdenough, in good spirits my code is open source :-). I just set up a new branch at my repo. And below is the offensive code in my BootScene:

  import { Scene } from 'phaser'
  import colourPalette from '../assets/tileset/colour_palette.png'
  import level1 from '../assets/tilemaps/level1.json'
  import player from '../assets/player.png'
  import playerDieSfxOgg from '../assets/audio/sfx_sounds_negative1.ogg'
  import playerDieSfxMp3 from '../assets/audio/sfx_sounds_negative1.mp3'
  import llpixel3Png from '../assets/font/llpixel3.png'
  import llpixel3Xml from '../assets/font/llpixel3.xml'

  export default class BootScene extends Scene {
    constructor () {
      super({ key: 'BootScene' })
    }

    preload () {
      this.load.image('player', player);
      this.load.spritesheet('colourPalette', colourPalette, {frameWidth: 35, frameHeight: 35});
      this.load.tilemapTiledJSON('level1', level1);
      this.load.audio('playerDiesSfx', [playerDieSfxOgg, playerDieSfxMp3]);
      this.load.bitmapFont('llpixel3', llpixel3Png, llpixel3Xml);
    }

    create () {
      this.scene.start('PlayScene')
    }
  }

In all honesty, I hope it's something really obvious and silly. I tried to load the fonts used in Phaser examples but no luck either, I keep getting the type error. It's even more strange, sometimes it works in Firefox very randomly but most times it throws an error.

msanatan avatar Jun 11 '18 03:06 msanatan

That's so strange. It works fine for me if I move the loading of the bitmap font above loading the tilemap.

i.e.

preload () {
  this.load.image('player', player);
  this.load.spritesheet('colourPalette', colourPalette, {frameWidth: 35, frameHeight: 35});
  this.load.bitmapFont('llpixel3', llpixel3Png, llpixel3Xml);
  this.load.tilemapTiledJSON('level1', level1);
  this.load.audio('playerDiesSfx', [playerDieSfxOgg, playerDieSfxMp3]);
}

I'll have to look through this in a bit more detail later on to see whether it is actually a bug here, or if it's in Phaser itself.

nerdenough avatar Jun 13 '18 04:06 nerdenough

That is really really interesting. And you're right, it works! Also, the fixed audio removes the requirement to disable web audio to make #18 work - now it's fine no matter how audio is played. I'll have a look as well I guess. Not sure what inspired you to switch things up but thanks!

msanatan avatar Jun 14 '18 02:06 msanatan