Dynamic loading of assets, entities and levels in ImpactJS

As a part of the JIPPI project, we added a create/destroy function to ImpactJS. With the create function, you could pass a string to let the game know which jigsaw puzzle to load. We didn't want the game to preload everything since the game consisted of 9 games and not all would be played during one session.

Due to the way ImpactJS is structured, it's actually quite easy to add dynamic preloading. Have you noticed the three functions module(), requires() and defines() at the top of each class? Did you know that when your files have been downloaded, all of these functions are executed?

These functions are executed so that ImpactJS gets a full list of all modules and the preloader gets a list of all assets to download. If you want to dynamically add a module, simply load it with XHR so that the browser can interpret it once it's downloaded. When the download has completed, call ig.main() to start the preloader and the game. Simple!

Let me show you how I did it.

In main.js I have a function called ig.create(params). One of the params is called 'character'. I load a baked js-file with all levels and entities for that character by doing this:

var char_to_load = 'characters/'+character+'.js';

var script = ig.$new('script');
script.type = 'text/javascript';
script.src = char_to_load;

script.onload = function() {};

script.onerror = function() {
    throw('Failed to load character ' + path + ' ');
};

ig.$('head')[0].appendChild(script);

This takes the character parameter, makes a full path to the baked file, creates a script tag and loads the file. You'll se that I haven't added any onload handler. Instead I use a timer to check for the length of ig._loadQueue.

When the file has been downloaded, the browser will interpret the file and execute any code that's supposed to be executed. By default, ImpactJS will register the module, add any assets to ig.resources and by calling the requires() function, ImpactJS traverses all the classes you have in your baked file. So, to make sure ImpactJS has traversed all files before I call ig.main(), I set up a timer that checks the length of the loadQueue.

ig.loadReadyInterval = setInterval(ig.checkReady, 250);

ig.checkReady = function(){
    if (ig._loadQueue.length === 0) {
        clearInterval(ig.loadReadyInterval);
        ig.main( ... );
    }
}

Once the loadQueue has a length of zero, I call ig.main().

Latest articles