DEV Community

Cover image for Phaser: Loading assets in a saner way
Núria
Núria

Posted on • Updated on

Phaser: Loading assets in a saner way

It's been some time since I talked about the code of the game, so I thought I'd share some of the changes I've made to make my life easier, in the shape of short posts. Today's turn is…

Loading Assets

As you may know, to add an asset to a Phaser scene, you need to call a load function with a key and the asset path as parameters. If the asset is a sprite, you also need to pass the frame width and height.

this.load.spritesheet('enemy', `/images/enemy.png`, {
  frameWidth: 50,
  frameHeight: 160
})

As you can imagine, when you have a lot of sprites, the preloading of all the assets becomes very verbose, and if you use the same sprite in different scenes, having the width and height hardcoded is tiresome and a potential source of bugs (if you change the size of the sprite, it's likely you forget to update it everywhere).

So the first step to improve this is to move all this hardcoded data to a constants.ts file. We've solved an issue but it's still quite verbose. This is how a scene preload function looked like at a certain point:

public preload() {
  this.load.audio(AUDIO.FIRE.KEY, `/sound/${AUDIO.FIRE.FILE}`)
  this.load.audio(AUDIO.STATIC.KEY, `/sound/${AUDIO.STATIC.FILE}`)
  this.load.audio(AUDIO.DROP.KEY, `/sound/${AUDIO.DROP.FILE}`)
  this.load.audio(AUDIO.BANG.KEY, `/sound/${AUDIO.BANG.FILE}`)
  this.load.image(
    IMAGES.BUILDING_BG.KEY,
    `/images/${IMAGES.BUILDING_BG.FILE}`
  )
  this.load.image(
    IMAGES.BUILDING_BG_2.KEY,
    `/images/${IMAGES.BUILDING_BG_2.FILE}`
  )
  this.load.image(IMAGES.FLOOR.KEY, `/images/${IMAGES.FLOOR.FILE}`)
  this.load.image(IMAGES.LADDER.KEY, `/images/${IMAGES.LADDER.FILE}`)
  this.load.image(IMAGES.BOXES.KEY, `/images/${IMAGES.BOXES.FILE}`)
  this.load.image(IMAGES.BUCKET.KEY, `/images/${IMAGES.BUCKET.FILE}`)
  this.load.image(IMAGES.WOOD.KEY, `/images/${IMAGES.WOOD.FILE}`)
  this.load.image(IMAGES.CLOTH.KEY, `/images/${IMAGES.CLOTH.FILE}`)
  this.load.image(IMAGES.DROP.KEY, `/images/${IMAGES.DROP.FILE}`)
  this.load.image(IMAGES.ROCK.KEY, `/images/${IMAGES.ROCK.FILE}`)
  this.load.image(IMAGES.METALBOX.KEY, `/images/${IMAGES.METALBOX.FILE}`)
  this.load.spritesheet(
    IMAGES.ANTENNA.KEY,
    `/images/${IMAGES.ANTENNA.FILE}`,
    {
      frameWidth: 160,
      frameHeight: 504
    }
  )
  this.load.spritesheet(
    IMAGES.FIREPIT.KEY,
    `/images/${IMAGES.FIREPIT.FILE}`,
    {
      frameWidth: 84,
      frameHeight: 60
    }
  )
}

I have a BaseScene with some common methods that all scenes inherit, to I created a loadAudio, loadImage and loadSprite functions there that receive the sprite constant as a parameter:

public loadSprite(SPRITE: SpriteAsset) {
  this.load.spritesheet(SPRITE.KEY, `/images/${SPRITE.FILE}`, {
    frameWidth: SPRITE.WIDTH,
    frameHeight: SPRITE.HEIGHT
  })
}

So the preload function ended up looking like this. It's actually loading more assets than before, but it's way easier to read:

public preload() {
  // Preload audio
  this.loadAudio(AUDIO.FIRE)
  this.loadAudio(AUDIO.STATIC)
  this.loadAudio(AUDIO.DROP)
  this.loadAudio(AUDIO.BANG)

  // Preload images
  this.loadImage(IMAGES.BUILDING_BG)
  this.loadImage(IMAGES.BUILDING_BG_2)
  this.loadImage(IMAGES.BUILDING_NIGHT_BG)
  this.loadImage(IMAGES.BUILDING_NIGHT_BG_2)
  this.loadImage(IMAGES.FLOOR)
  this.loadImage(IMAGES.WOOD)
  this.loadImage(IMAGES.CLOTH)
  this.loadImage(IMAGES.DROP)
  this.loadImage(IMAGES.ROCK)

  // Preload sprites
  this.loadSprite(SPRITES.METALBOX)
  this.loadSprite(SPRITES.LADDER)
  this.loadSprite(SPRITES.BUCKET)
  this.loadSprite(SPRITES.BOXES)
  this.loadSprite(SPRITES.ANTENNA)
  this.loadSprite(SPRITES.FIREPIT)
  this.loadSprite(SPRITES.BUGGY)
  this.loadSprite(SPRITES.STRANGER)
}

There's still room for improvement, for example I could have all the audio, images and sprites a scene needs in a constant, and load them all in a single call. But for now it's more than enough to make the code a bit more readable!

Top comments (2)

Collapse
 
michaeltharrington profile image
Michael Tharrington

This is an awesome series!

Just wanted to point out another relevant tag here in case you wanna use it - #showdev

#showdev

Show off what you've built!

No pressure of course to add the tag, just thinking it might be a good fit. 🙂

Collapse
 
pincfloit profile image
Núria

Thank you! I did not know this tag, I’ll be using it for sure 😄