Workaround for deprecated NMEPreloader

The NMEPreloader class is deprecated until OpenFL 5 is released.

If you get this message, we have changed the preloader system in OpenFL with a focus on simplicity, and removing the requirement for extending a special type.

At first, we wanted to implement it over the LoaderInfo object (similar to how Loader works), but unfortunately, this approach was not possible on Flash Player, though maybe we’ll visit that as an alternative in the future.

To create a standard preloader, don’t do anything! OpenFL will create a preloader for you. To create a custom preloader, use a class that extends Sprite, and specify the class name in your project.xml

<app preloader="MyPreloader" />
import openfl.display.Sprite;

class MyPreloader extends Sprite {
    
    public function new () {
        
        super ();
        
    }
    
}

A simple preloader will show while things are loading, and be removed automatically when preloading is complete.

To listen to progress events, add a listener to ProgressEvent.PROGRESS

import openfl.display.Sprite;
import openfl.events.ProgressEvent;

class MyPreloader extends Sprite {
    
    public function new () {
        
        super ();
        
        addEventListener (ProgressEvent.PROGRESS, onProgress);
        
    }
    
    private function onProgress (event:ProgressEvent):Void {
        
        trace (event.bytesLoaded, event.bytesTotal);
        
    }
    
}

You can listen for when preloading is complete using Event.COMPLETE

import openfl.display.Sprite;
import openfl.events.Event;
import openfl.events.ProgressEvent;

class MyPreloader extends Sprite {
    
    public function new () {
        
        super ();
        
        addEventListener (Event.COMPLETE, onComplete);
        addEventListener (ProgressEvent.PROGRESS, onProgress);
        
    }
    
    private function onComplete (event:Event):Void {
        
        trace ("complete");
        
    }
    
    private function onProgress (event:ProgressEvent):Void {
        
        trace (event.bytesLoaded, event.bytesTotal);
        
    }
    
}

After Event.COMPLETE, the preloader is unloaded automatically, and the application is started. If you prefer, you can choose when the preloader is unloaded. In this case, preventDefault () on the COMPLETE event, and dispatch Event.UNLOAD when you done.

import haxe.Timer;
import openfl.display.Sprite;
import openfl.events.Event;
import openfl.events.ProgressEvent;

class MyPreloader extends Sprite {
    
    public function new () {
        
        super ();
        
        addEventListener (Event.COMPLETE, onComplete);
        addEventListener (ProgressEvent.PROGRESS, onProgress);
        
    }
    
    private function onComplete (event:Event):Void {
        
        event.preventDefault ();
        
        Timer.delay (function () {
            
            dispatchEvent (new Event (Event.UNLOAD));
            
        }, 2000);
        
    }
    
    private function onProgress (event:ProgressEvent):Void {
        
        trace (event.bytesLoaded, event.bytesTotal);
        
    }
    
}

You may choose to unload based upon an animation, or a “Start” button that the user presses, or any other logic :slight_smile:

2 Likes

This works really well, but how would you add an image or graphic to the preloader to show the progress. Every time I try, it throws this error: “img/loadBar.png” exists, but only asynchronously"

Maybe you could embed="false" and use a Loader or BitmapData.loadFromFile to load the art assets you need, or you could consider using a separate “preloader” asset library, and loading that in:

(you can make as many asset libraries as you need, using whatever name makes sense, it’s just a way of bundling assets together in a simpler way)

1 Like

That works perfectly; however as a side effect, it .js file it produces is almost double and (for reasons I can’t figure out) load time (online) is about x5 now. At least its a start!

I discovered a problem with using multiple <assets …> tags in project.xml if you do it wrong. It ended up including the assets twice and basically doubled the filesize.

Look in your export/html5/bin/ folder to see if there are duplicates. It happens with other targets too. I first noticed in my app.swf properties/symbols using FlashDevelop. But there were duplicates in other targets too.

In my case I had something like this (don’t remember exactly)

<assets path="assets" include="*" />
<assets path="assets/sounds" include="*.mp3" if="flash" />
<assets path="assets/sounds" include="*.ogg" unless="flash" />

and it included 2 of each file because of the first line I think.

1 Like

I think that may be it. I now notice that (in the bin folder) there is an /img folder and an assets/img folder. I’ll have to look over the project file to see where I doubled up. Thanks dean.

Wow, that was it. I simply eliminated 1 line from my project.xml file (see below) and the pre-loader works in good time. Thanks to both of you so much!

<!-- assets -->
<icon path="assets/openfl.svg" />

<assets path="assets/img" rename="img" />
<assets path="assets/fonts" rename="fonts" />
<assets path="assets/sounds" rename="sounds" embed="false" if="html5" />

<!-- assets path="assets" rename="assets" exclude="preloader" / -->
<assets path="assets/preloader" rename="" embed="true" library="preloader" />

:sunglasses: Now that I think about it, I think it was an exclude that caused it for me, too. After including * and then excluding one file type in the same folder.