‘Cut the Rope’ HTML5 JavaScript Preloader

Screenshot of Cut the Rope HTML5 Javascript web appDevelopers from the popular iPhone game Cut the Rope and a crack team of HTML5 gurus from PixelLab, have developed an awesome JavaScript version that runs inside most modern web browsers using JavaScript and a number of powerful HTML5 features such as canvas and media APIs. You can find out how they did it from the behind-the-scenes video they’ve posted.

One of the interesting snippets from the dev blog is that the group behind the creation of the app have released an open-source preloader for JavaScript apps called PxLoader. It supports some extremely useful features such as being able to load in your canvas images in groups, use progress bars, get callbacks when various groups have loaded and supports a plug-in architecture so you can load in sounds too. It’s released under a fairly liberal MIT license and the PxLoader source is available on GitHub.

Image loading in Groups

A good example is using it in an HTML5 game to load menu sprites before actual game sprites since you would want the menu to display and load first. PxLoader can also provide progress updates to many listeners and will scope the updates and statistics to only the set of “tags” a listener is interested in, a tag being the text name of that group.

// Delay each image and append the timestamp to prevent caching 
var baseUrl = 'http://thinkpixellab.com/pxloader/slowImage.php?delay=1time=' + new Date, 
    $log = $('#sample3-log').val(''), 
    $menuProgress = $('#sample3-menuProgress').text('0 / 50'), 
    $gameProgress = $('#sample3-gameProgress').text('0 / 50'), 
    $totalProgress = $('#sample3-totalProgress').text('0 / 100'), 
    loader = new PxLoader(); 

// Queue 50 images for each section 
var addImagesForTag = function(tag, $progress) { 
    for(var i=0; i < 50; i++) { 
        var imageUrl = baseUrl + '&i=' + i + '&tag=' + tag; 
            pxImage = new PxLoaderImage(imageUrl, tag); 
        pxImage.imageNumber = i + 1; 
        loader.add(pxImage); 
    } 

    // add a listener to update progress for the tag 
    loader.addProgressListener(function(e) { 
        $progress.text(e.completedCount + ' / ' + e.totalCount); 
    }, tag); // scope listener to the current tag only 
}; 

addImagesForTag('menu', $menuProgress); 
addImagesForTag('game', $gameProgress); 

// Listen to every event to update total progress 
loader.addProgressListener(function(e) { 

    // log which image completed 
    var line = ' Image ' + e.resource.imageNumber + 
        ' Loaded [' + e.resource.tags[0] + ']\r'; 
    $log.val($log.val() + line); 

    // scroll to the bottom of the log 
    $log.scrollTop($log[0].scrollHeight); 

    // the event provides stats on the number of completed items 
    $totalProgress.text(e.completedCount + ' / ' + e.totalCount); 
}); 

// Start downloading images for tags in prioritized order 
loader.start(['menu', 'game'])

You can play with a working example of the group image loading on the PxLoader homepage (Sample 3).

How to call a block after a delay

On iOS and on OS X you sometimes need the User Interface to update after a short delay. The old way of doing it was calling the performSelector:withObject:afterDelay: selector on any NSObject subclass but that requires defining a new method in your class and you can only pass one object as a parameter.

Instead, you can use dispatch_after from the Grand Central Dispatch APIs to execute code within a block after a certain time interval. Don’t be afraid, it might be low-level C but you can cut and paste and just put your code inside and it will retain the variable scope that blocks usually do!

double delayInSeconds = 0.5;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){

  // Your code here

});