ActionScript 3 Tutorial 2 – Preloader

This tutorial covers some more of the basics of your chosen programming method while starting to build the framework of the game. By, er, ‘popular demand’, I’m going to show you how to make a Point and Click adventure game, where you have to collect items and solve puzzles in order to achieve a goal. For a good example of this, see The Outsider on the Games page.

Part 1 – Flash Professional

Open a new, blank AS3 file as we did for the previous tutorial. Go ahead and take the time to save it. I will refer to it as AS3Tut.fla for this tutorial.

So what do we start with? First, no matter what the type of game, you will probably need a title screen. But… there’s one thing that comes before that in most Flash games. Can you guess what it is?

A preloader is needed before a title screen, especially for bigger Flash games. A preloader stops your game at the first frame while the rest of the game is loading – otherwise, the player might get to a spot that hasn’t loaded yet, and the game will not proceed. Which is, of course, bad.

So, about that preloader. Some sites such as Newgrounds supply their own preloaders to use – just copy and paste one movie clip and you’re done. But as it turns out, it’s not hard to make your own, which is what we will do right now.

To start, create a text box on the stage. Change it to be a Dynamic text box, and give it an instance name of loadText. Giving something an instance name means that’s what you refer to it by in the code. Then, create a horizontal rectangle (around 175 px wide and 25 px tall), and make it into a movieclip symbol. Name it loadBar (in the Instance Name field, NOT the symbol name field that pops up when you are making it a symbol. Do give it a symbol name you can recognize, though.), then open the Actions panel. We’re gonna write some code! First I’ll lay it all out, then explain it afterwards. So type this:

stop();
this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, loadGame);
function loadGame(event:ProgressEvent):void {
var loadPercent:Number = event.bytesLoaded/event.bytesTotal*100;
loadBar.scaleX=loadPercent/100;
loadText.text=int(loadPercent)+"%";
if(loadPercent==100){
//We'll fill this in later!
}
}

First, we stop the movie from going on any further. Then, we add the event listener. Wait… what’s an event listener, you say? An event listener… listens for an event. There are many different types of event listeners – mouse listeners to catch when something is clicked, sound listeners to check when a sound finishes, and so on and so forth. There are many of them, and you will get to know a few of them, at least, quite well. We are using a Progress Event Listener, and attaching the listener to the stage’s loader info. This is expressed by this.loaderInfo.

Which brings us to referencing objects. If the object you want to mention is on the level you are currently on, all you have to do is say this.object.property. In fact, in most cases, you can even omit the ‘this’ part most of the time and it will still work. But if something you want is on a different level then what you are currently on, you have to reword it. For example, pretend you are IN ‘object’. object is on the stage, and there is also an object2 that is also on the stage. You want to change the width property of object2. But how do you do that from inside object (assuming, of course, that there is a situation that would require you to do that)? For that, MovieClip(parent).object2.width will work. MovieClip(parent) gets you back to the stage so you can reference a child of the stage, instead of a child of object. Better yet, you can use MovieClip(parent) multiple times to navigate multiple levels. In the same way, you can also delve deeper by specifying multiple objects (such as object1.object2.width, if object2 was in object1). Don’t worry if this seems confusing at first – there should be other chances to practice this later.

At any rate, our event listener is tracking the loading info. An event listener has two parameters: the event type and the name of the function that executes when the event listener is triggered. Our function is loadGame. The first thing in that function is making a variable. Dividing the bytes loaded by the total bytes of the program, and multiplying the result by 100, will calculate how much of the game is loaded. Hence the name of the variable, loadPercent. The next line stretches our rectangle movieclip to reflect this value. In other words, if 0% is loaded, the bar will be gone. If 50% is loaded, the rectangle will be at half its width, and finally, it will keep stretching until the whole game is loaded and it is the width you set it to originally. The next line sets the text box to tell the player how much is loaded by converting loadPercent to an integer (from a number, so we cut off the decimal places) and then adding a percent sign.

The if statement, as you might have guessed, is for when the game is 100% loaded. When that happens, we want a next button to appear. First, to make the next button, draw another rectangle to act as a play button, then slap some text on it to make the player aware about the play button. Select both the rectangle and the text (use shift+click to select multiple objects, or just use the mouse to drag over an area to select everything in that area. Also, remember that you have to double click on a shape to select BOTH the fill and the outline), and turn it into a Button symbol. Give it an instance name of playLoadButton.

Finally, put a title somewhere on that frame. I am naming this the Room Escape Game. If you want, you can make a neat logo, but because I am not known for my art skills, text will do for me.

So now your title/preloader screen should look something like this:

Title Screen

It doesn’t matter as much where everything is placed, but you should have a title, a loading bar, loading text, and a play button. Now, the last thing we need to do is to replace the commented line of code with actual code. Specifically, we need to make the play button invisible, and make it visible again when the game is ready to proceed. So just after the stop(); line, add this line of code:

playLoadButton.visible = false;

This line of code is easy enough to figure out. The button will become invisible. Now, replace the commented line of code in the if statement with:

playLoadButton.visible = true;

Which will make the button visible again when the game is fully loaded. When it is invisible, it can’t be clicked. Now the button will become visible and invisible, but it won’t do anything when clicked. Let’s fix that by using our friend, the Event Listener! Yes, that’s right, buttons use Mouse Event Listeners to detect when they are clicked, rolled over, and more. So, beneath playLoadButton.visible = true;, we’ll add

playLoadButton.addEventListener(MouseEvent.MOUSE_UP, onLoadPlay);

And then, directly after that, we need to define this new event listener.

function onLoadPlay(event:MouseEvent):void {
playLoadButton.removeEventListener(MouseEvent.MOUSE_UP, onLoadPlay);
gotoAndStop(2);
}

This function activates every time we click the play button. First, we remove the event listener we just set off. This is important because once the play button is pressed, we don’t need to use the event listener anymore. Event listener management can make or break performance in games. Just remember that once you are done with an event listener, it is usually a good idea to remove it. After we remove the listener, we then go to the second frame. The second frame, of course, is not there yet. So now we shall right click on the empty second frame in Layer 1 of the timeline and select Insert Keyframe. Make sure you are currently viewing that second keyframe, and then delete everything on the stage.

Before we go and test what we have, your first frame should have this code on it:

stop();
playLoadButton.visible = false;
this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, loadGame);
function loadGame(event:ProgressEvent):void {
var loadPercent:Number = event.bytesLoaded/event.bytesTotal*100;
loadBar.scaleX=loadPercent/100;
loadText.text=int(loadPercent)+"%";
if(loadPercent==100){
playLoadButton.visible = true;
playLoadButton.addEventListener(MouseEvent.MOUSE_UP, onLoadPlay);
function onLoadPlay(event:MouseEvent):void {
playLoadButton.removeEventListener(MouseEvent.MOUSE_UP, onLoadPlay);
gotoAndStop(2);
}
}
}

If you have the code right, go ahead and test it! Note that you can’t see the percent bar filling up, nor the text updating, as our game is a whopping 6 KB (without any extra embellishments that you may or may not have done), the game has virtually no loading time required.

Go to Control > Test Movie if you haven’t already. Here’s how to simulate downloading a game. In the game, go to View > Download Settings. There you can select a simulated download speed. Then, by clicking View > Simulate Download, you can simulate loading the game. However, that is of little use to us now – our game is mostly only one frame, and the preloader will only appear when the whole first frame loads, which is basically the whole game. Even on the slowest download setting, you will only see the loading text at 100%. But, this is good to know for the future. Another thing to mess around with is the Bandwidth Profiler. I have this on all the time, and people often ask me what it is, so I thought I would mention it. Click View > Bandwidth Profiler. Bam! You can see some more information on how big your game is.

That’s all for now. Next time, we’ll really start getting to work.

Source will come in Part 4.

One thought on “ActionScript 3 Tutorial 2 – Preloader”

  1. Thanks a lot for the Tuts. please am having a bit of problem with my welcome page on the game am creating it just keep going back to frame one after clicking the enter text which is suppose to take you main background just behind the animated one like a gate opening..

    here’s just the code I inserted in the action frame

    stop();

    button_btn.addEventListener(MouseEvent.CLICK, nextclick);
    function nextclick(event.MouseEvent): void{
    play();
    }

    Thanks

Leave a Reply

Your email address will not be published. Required fields are marked *