Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading multiple images with javascript

I am strugling to create a script to load multiple images for a game drawn on Canvas. The window seems to load without completing the load of all images. I've tried many ways but none of them seems to work. The function drawGameMenu() is called before the images are actually loaded and so the images are not drawn. If someone could help, I would be grateful. Here is my script, kind regards:

var imageNames = ["menuImage", "resetScoreButton", "instructionsButton", "playButton", "dialogPanel", "gamePlayImage", "exitButton", "timerPanel", "messengerPanel", "scoreBar", "yesButton", "noButton", "goButton"];
var imageFileNames = ["game_Menu", "reset_score_button", "instructions_button", "play_button", "dialog_panel", "game_play", "exit_button", "timer", "messenger_panel", "score_bar", "yes_button", "no_button", "go_button"];
var imageCollection = {};

window.addEventListener("load", function() {
    var u = imageNames.length - 1;
    for(i = 0; i <= u; i++) {
        var name = imageNames[i];
        imageCollection[name] = new Image();
        imageCollection[name].src = imageFileNames[i] + ".png";
        console.log(imageCollection[name]);
        imageCollection[name].addEventListener('load', function() {
            do {
                var x = imageCollection[name].complete;
            }
            while(x != true);
        });
    }   
    drawGameMenu();
});

I made some changes on the script and now it works on the PC browser, but not working on smartphone. The script is the following:

window.addEventListener("load", async function loadImageCollection() {
    var u = imageNames.length - 1;
    for(i = 0; i <= u; i++) {
        var name = imageNames[i];
        imageCollection[name] = new Image();
        imageCollection[name].src = imageFileNames[i] + ".png";
        do {
            await new Promise((resolve, reject) => setTimeout(resolve, 50));
            x = imageCollection[name].complete;
            console.log(x);
        }
        while(x == false);
    }   
    drawGameMenu();
});
like image 808
Luis Rito Filipe Avatar asked Dec 17 '22 20:12

Luis Rito Filipe


1 Answers

Keep it simple

Just use a simple callback and a counter to count of images as they load. Adding promises adds an additional level of complexity that is just a source of potential bugs. (the promise for each image and its callback and the need to call it on image load, and the need to handle promise.all with another callback)

const imageCollection = loadImages(
    ["menuImage", "resetScoreButton", "instructionsButton", "playButton", "dialogPanel", "gamePlayImage", "exitButton", "timerPanel", "messengerPanel", "scoreBar", "yesButton", "noButton", "goButton"],
    ["game_Menu", "reset_score_button", "instructions_button", "play_button", "dialog_panel", "game_play", "exit_button", "timer", "messenger_panel", "score_bar", "yes_button", "no_button", "go_button"],
    drawGameMenu  // this is called when all images have loaded.
);

function loadImages(names, files, onAllLoaded) {
    var i = 0, numLoading = names.length;
    const onload = () => --numLoading === 0 && onAllLoaded();
    const images = {};
    while (i < names.length) {
        const img = images[names[i]] = new Image;
        img.src = files[i++] + ".png";
        img.onload = onload;
    }   
    return images;
}
like image 53
Blindman67 Avatar answered Dec 31 '22 02:12

Blindman67