Skip to content

Loading assets

samme edited this page Feb 28, 2021 · 23 revisions

Strategy

  • Load assets before using them
  • Load shared assets in a "preloader" scene and nonshared assets in the scene they will be used in
  • Use a scene payload to load small assets before preload(), if needed
  • For special cases, run the scene loader manually and use event callbacks

Assets

There are many types, and you can read about all of them.

Assets need to be loaded before you can use them, but once loaded, they are available everywhere. It doesn't matter which loader or scene loaded them. Once loaded they are in the Texture Manager (this.textures) or the asset caches (this.cache).

Use unique keys (names) for assets.

The loader

Each scene has a loader plugin, this.load, for loading assets.

Adding files to the loader

All the "load" methods queue a file by key (name) and URL.

this.load.image('treasure', 'treasure.png');
// OR
this.load.image({ key: 'treasure', url: 'treasure.png' });

If you don't care for the key/URL distinction, pass the URL itself as key and omit url:

this.load.image('treasure.png');
// OR
this.load.image({ key: 'treasure.png'});

Then the asset key and URL are identical.

The loader will not add assets with duplicate keys (per asset type) at all:

// MISTAKE
this.load.image('sky', 'sky1.png');
this.load.image('sky', 'sky2.png');
// 'sky1.png' is loaded and stored as 'sky'.
// 'sky2.png' is not added or loaded.

Each "load" method can take an array, so there is no need to loop:

this.load.image([
  'conch.png',
  'treasure.png',
  'trident.png'
]);
this.load.spritesheet({
  { key: 'mermaid', url: 'mermaid.png', frameConfig: { frameWidth: 16, frameHeight: 16 } },
  { key: 'merman', url: 'merman', frameConfig: { frameWidth: 16, frameHeight: 16 } }
});

Thus you could write your own manifest pretty easily:

const files = {
  animation: {/* … */},
  audio: {/* … */},
  image: {/* … */},
  spritesheet: {/* … */},
};

this.load.animation(files.animation);
this.load.audio(files.audio);
this.load.image(files.images);
// …

A File Pack could do as well:

this.load.pack('pack1', {
  section1: {
    files: [
      { type: 'image', key: 'conch', url: 'conch.png' },
      { type: 'spritesheet', key: 'mermaid', url: 'mermaid.png', frameConfig: {/* … */} }
    ]
  }
});

preload()

Most of the time you will load assets in a scene preload() method.

When preload() returns, the loader starts automatically only if it has any files queued, then create() is called only after loading finishes.

If no files are queued, the loader doesn't start or complete and create() is called immediately. This is what happens during a typical scene restart. No loading at all happens during the second scene cycle.

Scene payload

A scene payload lets you load assets completely while the scene is starting:

const sceneConfig = {
  pack: {
    files: [
      { type: 'json', key: 'settings', url: 'settings.json' },
      { type: 'image', key: 'bar', url: 'bar.png' }
    ]
  },
  init: function () {
    this.game.registry.merge(this.cache.json.get('settings'));
  },
  preload: function () {
    const loadingBar = this.add.image(0, 0, 'bar');
    // …
  }
};

It's best for small assets you want to use right away, before create(). The scene does nothing at all until the payload completes.

Removing assets

You can remove assets to save memory.

Remove textures from the Texture Manager:

this.textures.remove('conch');

and other assets from their respective caches:

this.cache.audio.remove('chime');
this.cache.json.remove('settings');
Clone this wiki locally