Make a preloader [How to]

6 posts

Flag Post

I’m feeling generous again, so I’ve decided to make another forum-based tutorial. But this time it’s…

===

Preloaders!

A preloader basically loads your game/movie so when you play it, it wont lag. Ok, all you need are 2 blank keyframes on your main timeline (F7). On your first BLANK keyframe insert this code into the AS box (lets hope this turns out right _):

var bytes = _root.getBytesTotal();
var bytes_loaded = _root.getBytesLoaded();
percent = int((bytes_loaded)/(bytes)*100) + "%";
if (bytes_loaded == bytes) {gotoAndPlay(3)}

What does that do, you ask? Well it tells Flash “Hold up bud, you’re not moving until you’re loaded ALL of this guys movie. You hear?!” Ok so it doesn’t really say that, but in general terms yes…

Now on your second BLANK keyframe insert this:

gotoAndPlay(1)

This will make your movie play after it’s loaded. Now start your movie of frame 3 :D

===

~Penboy

 
Flag Post


Some tips:

Its better to use the onEnterFrame event instead of the 2 frame loop trick. We stopped doing that a few years back. Also, instead of using “int()”, use Math.round().

If you do it this way, you can put it on one frame and it will also be smoother (added comments for reference):


stop();

// Get total bytes for the swf
var total:Number = _root.getBytesTotal ();

onEnterFrame = function ()
{
	// Get loaded bytes for the swf
	var loaded:Number = _root.getBytesLoaded();
	
	// Calculate percentage loaded
	var percent:Number =  ( loaded / total ) *100;
	
	// Display in a text field
	my_text.text = Math.round ( percent ) + "%";
	
	// Check if entire movie has loaded
	// You can change 100 to a lower number if you want it
	// to skip the rest of the preloading at a certain point
	if ( percent == 100 ) {
		delete onEnterFrame;
		play();
	}
}


You can declare your variables outside your EnterFrame event as well if you like. In this case its not really an issue.

If you are the type of person that likes to code inline, you can crunch it a bit if you like. There are a few different ways to handle it.


stop();
onEnterFrame = function (){
	var percent:Number = ( _root.getBytesLoaded() / _root.getBytesTotal () ) *100;
	my_text.text = Math.round ( percent ) + "%";
	if ( percent == 100 ) {
		delete onEnterFrame;
		play();
	}
}


Thanks for your post Penboy, keep it up! Congrats on getting the tags working ;)

I’m so tired… :D


 
Flag Post

To end that loop I wouldn’t use Math.round( ... ) == 100. I would check _root.getBytesLoaded() == _root.getBytesTotal() or use Math.floor( ... ). Using Math.round could fall through before the movie is fully loaded (99.5% rounds to 100%), unless that’s the intent.

 
Flag Post

I dont normally use it that way myself, but either way its irrelevant because a fraction as small as 0.5% is almost never an issue. Penboy already demonstrated the loaded == total method, so I demonstrated the % == 100 way for those who want to do something different. Remember, Flash is meant to be a streaming product, so if it jumps the gun the rest of the movie will load in the frames along the way. The whole point of demonstrating % == 100 was for those people who like to end their preloaders at less than 100% anyway.

Math.round is only used for the display component, so you can either not use it at all or move it to just the display line (if you feel 0.5% is going to kill your loading), which makes the 0.5% issue non existent. I usually use it on the line for the display component myself anyways, like so:

// Calculate percentage loaded
var percent:Number = ( loaded / total ) *100;

// Display in a text field
my_text.text = Math.round ( percent )+ "%";

To avoid confusion for others though, I will update the sample code with my method above. Thanks.

 
Flag Post

Yeah, it’s not really a bug and it would work fine, but it just wasn’t strictly correct so it makes for a bad example. If the whole point was to help people who want to stop preloading at less than 100% then it might have been worth mentioning because it sure wasn’t obvious.

If I were intending to play before the movie was fully loaded there would be some kind of explicit fudge factor (e.g. “at least level 1 loaded”) and probably an adjustment for estimated download speed. For the most part Flash games are small enough to where loading to 100% just makes the most sense. I would also make the display scale from 0-100% rather than just stopping at some arbitrary 64% or something.

On a more useful note, the technique for doing a preloader in AS3 with mxmlc is a lot different and totally undocumented (at least none that I found at first search). Keith Peters of Bit-101 managed to figure it out and came up with a solution that he blogged about here: http://www.bit-101.com/blog/?p=946

 
Flag Post


If the whole point was to help people who want to stop preloading at less than 100% then it might have been worth mentioning because it sure wasn’t obvious.


That was not the whole point but it was a part of the reason and was alluded to in the code comments.


bq. For the most part Flash games are small enough to where loading to 100% just makes the most sense. I would also make the display scale from 0-100% rather than just stopping at some arbitrary 64% or something.


Agreed, I personally dont like to stop before 100% – but some people do. I always use a graphical element as well myself. But for the same reasons a possible rounding advancement becomes a non issue. As was mentioned, there are different ways to handle it. Its the different principles that are demonstrated.

Additionally as I said I dont even do it that way anyway, I put my rounding on the line for the display (if I use a textfield or a timeline animation, if its a graphical element that scales then I dont round at all). I only threw it on the above line because it was late and I was tired (as I said in my post). I’m a very strict coder myself, however in this case I could care less if a person did it with any of the particular ways mentioned, since its effectiveness is essentially the same.

Thanks for catching it anyhow.