Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A function to preload images - need to draw them now, but how?

I'm dabbling with canvas. And I'm a little lost on something.

I have this function:

function preloadimages(arr) {
        var newimages = []
        var arr = (typeof arr != "object") ? [arr] : arr
        for (var i = 0; i < arr.length; i++) {
            newimages[i] = new Image()
            newimages[i].src = arr[i]
        }
    }

And I call it like so:

preloadimages(['images/background.png', 'images/hero.png', 'images/monster.png']);

The only problem is, I don't know how to then draw them again later.

If I was preloading one image inside my js I would say:

var bgOk = false;
var bg = new Image();
bg.onload = function () {
    bgOk = true;
};
bg.src = "images/background.png";

and then further down when I wanted it drawn I would say:

if (bgOk) {
        context.drawImage(bg, 0, 0);
    }

And that would be that. The problem is I have made a preloader class, I don't really know how now to call in just the image I want to draw now, or even how to implement the bgOk idea so that if it loaded ok, I can draw it, and if not, leave it alone.

Could someone advise me on this? I'm basically just trying to go more class based rather than the dirty great mess I normally have with a huge javascript file that is ugly and not as maintainable.

like image 322
David G Avatar asked Dec 15 '22 09:12

David G


1 Answers

This seems to be a complicated problem, but in reality isn't as bad as it looks. If you want to use pre-existing code, or just want to look at something for ideas you can have a look at: http://thinkpixellab.com/pxloader/ This library was used in the HTML5 version of Cut The Rope.

A simple custom implementation could be something like the following:

function loadImages(arr, callback) {
    this.images = {};
    var loadedImageCount = 0;

    // Make sure arr is actually an array and any other error checking
    for (var i = 0; i < arr.length; i++){
        var img = new Image();
        img.onload = imageLoaded;
        img.src = arr[i];
        this.images[arr[i] = img;
    }

    function imageLoaded(e) {
        loadedImageCount++;
        if (loadedImageCount >= arr.length) {
            callback();
        }
    }
}

And then you can call it like this:

var loader = loadImages(['path/to/img1', 'path/to/img2', 'path/to/img3'], function() {
    ctx.drawImage(loader.images['path/to/img1']); // This would draw image 1 after all the images have been loaded

    // Draw all of the loaded images
    for (var i = 0; i < loader.images.length; i++) {
        ctx.drawImage(loader.images[i]);
    }
});

If you want more details on asset loading you can have a look at the asset loading section of Udacity's HTML5 Game Development course https://www.udacity.com/course/cs255

like image 152
HJ05 Avatar answered Feb 23 '23 13:02

HJ05