@cpb is absolutely correct. Start with preloading images and act after everything has been loaded.
For Snowman specifically, here is some code using the Preload-It code you linked to, @pseudavid.
I’ll include it all in Twee code and then discuss what is going on in each step.
:: StoryTitle
Snowman: Preloading Images
:: UserScript[script]
// Use jQuery's getScript() function to get and load a remote JS file
$.getScript( "https://unpkg.com/preload-it", function( data, textStatus) {
// Prepare the loaded Preload library
const preload = Preload();
// Define what should happen when complete
preload.oncomplete = function(items) {
// Create an empty 'images' object
window.images = {};
// Add a property to window.images
window.images = items;
// Show() the correct starting passage
window.story.show("True Beginning");
};
// Finally, fetch the files
preload.fetch([
'https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg'
]);
});
:: Start
Loading...
:: True Beginning
Images have loaded and now we can work!
<img src="<%= window.images[0].url %>" >
Using getScript()
Using jQuery’s getScript() function. The jQuery library is available in Snowman. It can be used anywhere and, because these images need to be loaded before anything else, putting this code in the Story JavaScript section makes the most sense.
The function can take multiple arguments, but we care about two of them: what to load and what should happen after it loads. In this example, the source “https://unpkg.com/preload-it” is loaded. jQuery retrieves this source and then executes it, loading and creating anything the script tells it to do.
In the “what should happen after loading argument,” there is a function. This helps us define that callback @cpb was talking about. The callback here waits for the script to be loaded and then runs its own code.
Using Preload-It
Based on the exact instructions from Preload-It, the code looks roughly like the following:
const preload = Preload();
preload.oncomplete = function(items) {
..
};
preload.fetch([
...
])
(For those not as knowledgeable about JavaScript ES6, Preload-It uses arrow functions for things. I’ve converted them back into “normal” ES5 functions.)
Using this library, we prepare it, define what should happen after it fetches, and then, finally, actually fetch a file.
Working with Snowman
You didn’t include which version of Snowman you are using, @pseudavid, so I wrote code that will work across 1.3, 1.4, and 2.0.2.
It starts by defining a new global property, window.images
. Defining this allows us to load all the images and then access them in future passages.
Next, it calls window.story.show()
. (I’ll link to the 2.X branch documentation here.) By supplying the name of a passage, the function immediately “goes” to that passage, replacing the current passage’s contents.
In my example, the first, starting passage (called “Start”) has text that reads Loading...
. It will show this until the call to the function window.story.show()
when its contents are replaced with the contents of the passage “True Beginning”.
Splitting it up like this allows for adding in instructions, details, or just a loading message in one passage and then having its contents be replaces when the game finally loads everything.
Displaying Loaded Images
Finally, images are displayed using their url
property of each entry in the now window.images
array.
Using value interpolation, the Underscore template system can write a variable’s value into a passage. In this example, the code is the following:
<img src="<%= window.images[0].url %>" >
It write the url
property of the first (0) entry in the window.images
array to the passage and then, when the browser sees the HTML code, it would see it as the following:
<img src="https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg">
Moving Beyond the Example
To extend this example, list all of the images to fetch in the preload.fetch()
function call and then, to use them in passages, write their values through where they are in the array. That is, window.images[X].url
depending on which number they are in the array sequence.
Depending on the number and size of the images, as cpb mentioned, this could be consuming at first. However, once loaded, displaying them will be very fast.
As I mentioned, and many, many games do, including something for the player to read or do as the loading is going on can “hide” the experience. You could just as easily add a link to the starting passage that allows them to continue only after all the loading is finished. That’s a very common game design solution.