Way to use custom preloader from swf-library

I have to use preloader from swf-library, so, i have extended NMEPreloader and tried to load library in constructor - Assets.loadLibrary (“lib”, function (_) {…} ); But library not loaded and Assets.hx throws run-time message - Assets.hx:800: [Assets] There is no asset library named “lib”. Then I tried to call Assets.loadLibrary from Timer.delay function, and everything worked fine. But this trick wont work when swf is uploaded to a real server(I think delay value depends from connection speed). Library only loaded when i press refresh-button in browser but not the first time. Looks like I have to first load the swf-preloader and only then allow NMEPreloader to load the rest of content. So my question is - how can I do this, or is there an other way to solve my problem?

1 Like

slightly rephrase the question: how to use the assets of a small swf-library without waiting to load the entire finale swf. Something like @:bitmap("img.png") class myImg extends BitmapData {} but for swf.

Try <library path="to/my.swf" preload="true" />

This was added recently to preload SWF assets before beginning the project – it sounds like this is just what you are looking for. Using the latest versions, give it a try and see if it works for you :slight_smile:

1 Like

This is not working for me :cry: . The SWF is loading just after the preload and not before.
The SWF is only 22kb. On project.xml I have:

<library id="PreloaderLib" path="libs/Preloader2014.swf" preload="true"/>

I have other libraries that I’m loading for other things but without the true preload.

This is the preloader code:

package loaders;

import flixel.system.FlxPreloaderBase;
import openfl.Assets;
import openfl.display.MovieClip;
import openfl.display.Sprite;

class Preloader extends NMEPreloader
{

	var preloaderSwf:MovieClip;
	
	public function new() 
	{
		super();
		
		Assets.loadLibrary("PreloaderLib", swfAssetLoaded);		
	}
	
	function swfAssetLoaded(_):Void
	{
		preloaderSwf = Assets.getMovieClip("PreloaderLib:preloader");
		addChild(preloaderSwf);
	}
}

I also tried with generate= “true” to be able to call the class but this is not working neither for the preloader.

It is impossible to do a preloader using a swf on Openfl?

Ah, perhaps I misunderstood the question.

The preload attribute allows a SWF library to be loaded automatically, preventing the need to call Assets.loadLibrary manually:

It is still available after the OpenFL preloader is finished. So you’re trying to use SWF assets as the preloader, instead of the OpenFL one? I’m not sure there’s a way to do this at the moment

Ouch :disappointed: My customer sent me a .fla to use as the preloader. I’ll have to reproduce it by code now so I can use those assets on the preloader.

It’s not impossible, but just not supported out of the box, what target are you using?

My target is only flash now.

If you can use two SWF files, that would be the easiest solution – one to preload, then one for the OpenFL content. If you can’t, then I’m happy to brainstorm, it’s not impossible. In fact, you might even be able to embed using the @:bytes tag, then using a Loader to load from bytes

I can’t use two swfs.

I’m lost by the second solution. I’m in the right direction here? Where do I learn more about this kind of things?

@:ByteArray("assets/Preloader2014.swf")
class PreloaderSWF extends  ByteArray{}

class Preloader extends NMEPreloader
{
	public function new() 
	{
		super();
		var loader:Loader = new Loader();
		loader.addEventListener(Event.COMPLETE, swfLoaded);
		loader.loadBytes(new PreloaderSWF());
        }

	function swfLoaded(e:Event)
	{
		var preloaderMov:MovieClip = cast(e.target.data, MovieClip);
		addChild(preloaderMov);
	}

}

I found more info here:
http://old.haxe.org/manual/tips_and_tricks

so it has to be @:file and not @:bytes :smiley:

Now It doesn’t crash but it is only playing the sound but not the image of the SWF. This is my code now. I’m extending Haxeflixel Loader but Is similar to Nmepreloader.

What can be wrong?

package loaders;

import flixel.system.FlxPreloaderBase;
import format.SWF;
import openfl.Assets;
import openfl.display.Loader;
import openfl.display.MovieClip;
import openfl.display.Sprite;
import openfl.events.Event;
import openfl.utils.ByteArray;

@:file("assets/Preloader2014.swf")
class PreloaderSWF extends  ByteArray{}


class PreloaderBar extends FlxPreloaderBase
{

	public function new(MinDisplayTime:Float=6, ?AllowedURLs:Array<String>) 
	{
		super(MinDisplayTime, AllowedURLs);		
	}
	
	override private function create():Void
	{
		super.create();
		
		var loader:Loader = new Loader();
		loader.addEventListener(Event.COMPLETE, swfLoaded);
		var bytes = new PreloaderSWF();
		loader.loadBytes(bytes);
	}
	
	function swfLoaded(e:Event)
	{
		var preloaderMov:MovieClip = cast(e.target.data, MovieClip);
		addChild(preloaderMov);
	}
		
}

Perhaps you could try adding your own custom sprite to the create method manually, to make sure that a quick drawn rectangle or something is displaying.

Also, I think you need to listen to loader.contentLoaderInfo.addEventListener and not loader.addEventListener, if you are only adding the loaded content, rather than fading it in or doing more, you might also want to just addChild (loader) which might be simpler

Thanks a lot, majesty!

I’ll leave my class here just in case someone needs it:

@:file("libs/Preloader2014.swf")
class PreloaderSWF extends  ByteArray{}


class PreloaderBar extends FlxPreloaderBase
{

	public function new(MinDisplayTime:Float=6, ?AllowedURLs:Array<String>) 
	{
		super(MinDisplayTime, AllowedURLs);		
	}
	
	override private function create():Void
	{
		super.create();
		
		var loader:Loader = new Loader();
		loader.contentLoaderInfo.addEventListener(Event.COMPLETE, swfLoaded);
		var bytes = new PreloaderSWF();
		loader.loadBytes(bytes);
	}
	
	function swfLoaded(e:Event)
	{
		var preloaderSWF:MovieClip = cast(e.target.content, MovieClip);
		//Movieclip on the main timeline:
		var preloader:MovieClip = cast(preloaderSWF.getChildByName("_preloader"), MovieClip);
		preloader.gotoAndStop(0);
		addChild(preloader);
	}
}
1 Like

Awesome! Glad you got this working, and glad you shared your working code.

I’ll have to keep this in mind in the future with the SWF library, in case preloaders want to use these assets on other targets, too :slight_smile: