Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning ActionScript 2.0 2006

.pdf
Скачиваний:
103
Добавлен:
17.08.2013
Размер:
12.47 Mб
Скачать

Chapter 8

Try It Out

Using the Monolithic Approach

In Chapter 6, you completed a number of Try It Out exercises that worked with a portfolio project. Now you extend that project to incorporate a pre-loader.

1.Open the file <downloaded files>/Chapter 8/portfolio v6/portfolio.as.

2.Go through the file looking for all instances of _level0 and change them to the this keyword. For example, _level0.createEmptyMovieClip should be this.createEmptyMovieClip and _level0[“screenHolder”] should be this[“screenHolder”]. Four changes are needed.

3.Save the file and close it.

4.Go to <downloaded files>/Chapter 8/portfolio v6, and open the file portfolio.fla.

5.Publish the movie (File Publish), and then close the file.

6.Create a new Macromedia Flash document by selecting File New and choosing Flash Document from the New Document panel.

7.Click the first frame in the timeline, open the Actions panel (Window Development Panels Actions), and type in the following ActionScript code:

#include “loaderShim.as”

8.Open up the components panel (Window Components) and in the User Interface section, open the library panel (Window Library). Drag the Loader and the ProgressBar components to the middle of the library panel. If you are using Flash MX 2004, drag the two components onto the stage and then delete them from the stage.

9.Select Modify Document, and set the dimensions to 800 wide by 600 high.

10.Select File Save As, name the file loaderShim.fla, and save it in the same directory as portfolio.fla.

11.Create a new Macromedia Flash document by selecting File New and choosing ActionScript File from the New Document panel.

12.Name it loaderShim.as and save it in the directory containing the Flash project file.

13.Enter the following code into the new ActionScript file:

this.createEmptyMovieClip(“myContent”, this.getNextHighestDepth()); this.createEmptyMovieClip(“progressMovie”, this.getNextHighestDepth()); progressMovie._x = 60;

progressMovie._y = 120; progressMovie.createTextField(“percentDoneLabel”, ;

progressMovie.getNextHighestDepth(), 40, 0, 100, 20);

var loadListener:Object = new Object(); loadListener.onLoadStart = function(contentHolder:MovieClip)

{

progressMovie._visible = true; contentHolder._visible = false; contentHolder.stop();

218

Pre-Loading Movies

};

loadListener.onLoadProgress = function(contentHolder:MovieClip, ; bytesLoaded:Number, bytesTotal:Number)

{

var percentDone:Number = bytesLoaded / bytesTotal * 100; showProgress(percentDone, progressMovie);

};

loadListener.onLoadComplete = function(contentHolder:MovieClip)

{

progressMovie._visible = false; contentHolder._visible = true; contentHolder.play();

};

var contentLoader:MovieClipLoader = new MovieClipLoader(); contentLoader.addListener(loadListener); contentLoader.loadClip(“portfolio.swf”, myContent);

function showProgress(percentDone:Number, progressBarHolder:MovieClip) : Void

{

var barWidth:Number = percentDone;

progressBarHolder.percentDoneLabel.text = String(Math.ceil(percentDone))+” %”; progressBarHolder.clear();

//Draw a border progressBarHolder.moveTo(0, 20); progressBarHolder.lineStyle(1, 0x666666); progressBarHolder.lineTo(100, 20); progressBarHolder.lineTo(100, 30); progressBarHolder.lineTo(0, 30); progressBarHolder.lineTo(0, 20);

//Draw the bar progressBarHolder.moveTo(0, 20); progressBarHolder.beginFill(0xCCCCCC, 100); progressBarHolder.lineTo(barWidth, 20); progressBarHolder.lineTo(barWidth, 30); progressBarHolder.lineTo(0, 30); progressBarHolder.lineTo(0, 20); progressBarHolder.endFill();

}

14.Save the file (File Save), return to the Macromedia Flash project file, and select Control Test Movie. The loader should show up briefly and then the portfolio interface should take its place.

How It Works

This exercise makes use of the MovieClipLoader class instead of the Loader and ProgressBar components because using the MovieClipLoader class keeps the loader shim very small, on the order of 1 KB versus 32 KB.

219

Chapter 8

The first part involves changing a few references from _level0 to the this keyword. The _level0 keyword is an absolute reference that always refers to the base timeline. Unfortunately, because the preloader loads the content into its own nested movie clip rather than onto the main timeline, the content no longer sits directly on _level0. The this reference in the context of movie clips is a relative reference to whatever movie clip the code happens to sit inside. If you had tried to load the content through the pre-loader, the content would be visible but none of the buttons would work. Clearly, using the relative this reference instead of the absolute _level0 reference makes content portable.

Within the loaderShim.as file, the first few lines shown in the following code set up the movie clips. First, a movie clip is created into which the main content will be loaded. Next, a second movie clip is created to hold the progress bar graphics. That movie clip is positioned, and a text field inserted:

this.createEmptyMovieClip(“myContent”, this.getNextHighestDepth()); this.createEmptyMovieClip(“progressMovie”, this.getNextHighestDepth()); progressMovie._x = 60;

progressMovie._y = 120; progressMovie.createTextField(“percentDoneLabel”, ;

progressMovie.getNextHighestDepth(), 40, 0, 100, 20);

An event listener is then created. The content clip is hidden and the progress bar is revealed once the load has begun:

var loadListener:Object = new Object(); loadListener.onLoadStart = function(contentHolder:MovieClip)

{

progressMovie._visible = true; contentHolder._visible = false; contentHolder.stop();

};

The following code updates the progress bar every time a chunk of content is downloaded:

loadListener.onLoadProgress = function(contentHolder:MovieClip, bytesLoaded:Number, bytesTotal:Number)

{

var percentDone:Number = bytesLoaded / bytesTotal * 100; showProgress(percentDone, progressMovie);

};

Once all the content has been downloaded, the progress bar is hidden, the content is displayed, and playback begins in case the content consists of more than one frame:

loadListener.onLoadComplete = function(contentHolder:MovieClip)

{

progressMovie._visible = false; contentHolder._visible = true; contentHolder.play();

};

The movie clip loader is created, is linked with the event listener, and the load process is initiated:

var contentLoader:MovieClipLoader = new MovieClipLoader(); contentLoader.addListener(loadListener); contentLoader.loadClip(“portfolio.swf”, myContent);

220

Pre-Loading Movies

The showProgress() function redraws the progress bar and updates the text field to reflect how much content has downloaded:

function showProgress(percentDone:Number, progressBarHolder:MovieClip) : Void

{

var barWidth:Number = percentDone;

progressBarHolder.percentDoneLabel.text = String(Math.ceil(percentDone))+” %”; progressBarHolder.clear();

//Draw a border progressBarHolder.moveTo(0, 20); progressBarHolder.lineStyle(1, 0x666666); progressBarHolder.lineTo(100, 20); progressBarHolder.lineTo(100, 30); progressBarHolder.lineTo(0, 30); progressBarHolder.lineTo(0, 20);

//Draw the bar progressBarHolder.moveTo(0, 20); progressBarHolder.beginFill(0xCCCCCC, 100); progressBarHolder.lineTo(barWidth, 20); progressBarHolder.lineTo(barWidth, 30); progressBarHolder.lineTo(0, 30); progressBarHolder.lineTo(0, 20); progressBarHolder.endFill();

}

When you try this out, the loader only shows up for a moment, largely because loading local content is very fast and also because the file is still fairly small. Placing the .swf files on a server is a better way of seeing the effect. As more content is placed into the portfolio, the larger it will get and the longer the progress bar will stay up.

The Split-Up Movie Approach

You might not want to use the monolithic movie approach for a couple of reasons. As project size gets large, initial load time can become quite significant. Also, changes and additions to the project must be made directly to the main Flash project file. It is generally easier to maintain projects that are split up into smaller chunks. Splitting a movie into chunks also lowers initial load time and saves bandwidth. The split-up movie is generally implemented in an on-demand fashion, where content for a specific section loads only once the user elects to visit that section. If a section goes unvisited by the user, the content for that section does not load.

The cost of the split-up movie approach is, of course, a slight increase in complexity. The following Try It Out shows how to use this approach.

Try It Out

Using the Split-Up Movie Approach

This exercise builds on the previous Try It Out. You learn to separate content from the main project, and then call individual screens as needed.

221

Chapter 8

1.Open the completed portfolio.fla and portfolio.as files from the previous Try It Out, or open up the source .fla and .as files from the book’s source files at <downloaded files>/ Chapter 8/portfolio v7/portfolio.fla and <downloaded files>/Chapter 8/ portfolio v7/portfolio.as.

2.Select the portfolio.fla document, open the Library panel (Window Library), and look for the movie clip symbol at /screens/home/screen_home. Double-click the symbol to take it into edit mode.

3.Drag across all the keyframes to select them. Alternatively, click the keyframe on the Menu Marker layer, and then shift+click the keyframe on the Featured Photo layer. Select Edit Timeline Copy Frames.

4.Create a new Macromedia Flash document.

5.Select the empty keyframe in the new document’s timeline. Select Edit Timeline Paste Frames.

6.Open the properties panel (Window Properties) and select Edit Select All. Enter an x value of 25 and a y value of 50.

7.Select Modify Document, and set the dimensions to 800 wide and 600 high.

8.Save the document and name it home.fla.

9.Select File Publish to create a .swf file.

10.Repeat steps 2 to 11 for the library symbols at /screens/tutorials/screen_tutorial and at

/screens/photography/screen_photography. Save the new files as tutorials.fla and photography.fla.

11.Return to portfolio.fla, and delete all library elements in the screens folder.

12.In portfolio.fla, open the User Interface section of the components panel. Open the Library panel (Window Library), and drag the Loader and the ProgressBar components to the middle of the Library panel. If you are using Flash MX 2004, drag the two components onto the stage and then delete them from the stage. Save portfolio.fla to make sure you do not lose your changes.

13.Go to the portfolio.as ActionScript file. Make sure the contents of that file look like the following code. The bold lines indicate new or modified code:

//Set up code to respond to main menu buttons

home_btn.onRelease = function()

{

gotoScreen(“home”);

}

tutorials_btn.onRelease = function()

{

gotoScreen(“tutorials”);

}

photography_btn.onRelease = function()

{

222

Pre-Loading Movies

gotoScreen(“photography”);

}

function gotoScreen(screenName:String):Void

{

loaderComponent.unload(); loaderComponent.load(screenName + “.swf”);

}

function init():Void

{

var screenHolderHandle:MovieClip;

var loadHandler:Object = new Object();

this.createClassObject(mx.controls.Loader, “loaderComponent”, ; this.getNextHighestDepth());

this.createClassObject(mx.controls.ProgressBar, “progressComponent”, ; this.getNextHighestDepth());

progressComponent._x = Stage.width / 2 - progressComponent._width / 2; progressComponent._y = Stage.height / 2 - progressComponent._height / 2;

progressComponent.source = loaderComponent; progressComponent.setStyle(“color”, 0x888888); progressComponent.setStyle(“fontSize”, 12); progressComponent.setStyle(“themeColor”, 0x888888);

loadHandler.progress = function(eventObject:Object)

{

loaderComponent.content.stop(); progressComponent._visible = true;

}

loadHandler.complete = function(eventObject:Object)

{

loaderComponent.content.play(); progressComponent._visible = false;

}

loaderComponent.scaleContent = false; loaderComponent.addEventListener(“progress”, loadHandler); loaderComponent.addEventListener(“complete”, loadHandler);

gotoScreen(“home”);

}

init();

14.Save the file, return to portfolio.fla, and select Edit Publish.

15.Open the file loaderShim.fla and select Control Test Movie. There should be two initial flashes of the progress bar, and clicking each menu item should result in a short flash of the progress bar. You may not see the initial flash of the progress bar until you try uploading the files to a server and view the project through a browser.

223

Chapter 8

How It Works

When you previously worked on this project, each screen was a movie clip in the library that was attached to the screen through the attachMovie() method. In this exercise, each of those movie clips was placed in its own .fla file and published. Because the screens in the portfolio.fla library have linkage IDs, they are still included in the published file. You no longer need any of the screens, so it is easiest just to delete them from the library.

Note that in this project you can choose whether to use the initial loader shim. The size of the parent movie is smaller than before, but it is still a good idea to use the shim.

The button handler code has not changed at all from last time:

// Set up code to respond to main menu buttons home_btn.onRelease = function()

{

gotoScreen(“home”);

}

tutorials_btn.onRelease = function()

{

gotoScreen(“tutorials”);

}

photography_btn.onRelease = function()

{

gotoScreen(“photography”);

}

A small change to the gotoScreen() method lets you use the Loader component to unload the previous screen and load the next screen:

function gotoScreen(screenName:String):Void

{

loaderComponent.unload(); loaderComponent.load(screenName + “.swf”);

}

Finally, the init() function is changed to set up the components:

function init():Void

{

var screenHolderHandle:MovieClip;

var loadHandler:Object = new Object();

this.createClassObject(mx.controls.Loader, “loaderComponent”, ; this.getNextHighestDepth());

this.createClassObject(mx.controls.ProgressBar, “progressComponent”, ; this.getNextHighestDepth());

progressComponent._x = Stage.width / 2 - progressComponent._width / 2; progressComponent._y = Stage.height / 2 - progressComponent._height / 2;

progressComponent.source = loaderComponent; progressComponent.setStyle(“color”, 0x888888);

224

Pre-Loading Movies

progressComponent.setStyle(“fontSize”, 12); progressComponent.setStyle(“themeColor”, 0x888888);

loadHandler.progress = function(eventObject:Object)

{

loaderComponent.content.stop(); progressComponent._visible = true;

}

loadHandler.complete = function(eventObject:Object)

{

loaderComponent.content.play(); progressComponent._visible = false;

}

loaderComponent.scaleContent = false; loaderComponent.addEventListener(“progress”, loadHandler); loaderComponent.addEventListener(“complete”, loadHandler);

gotoScreen(“home”);

}

init();

The implementation of the pre-loader is very similar to the load shim created in the previous Try It Out exercise. One thing to note here is that the re-factoring that you did in the Chapter 6 exercises paid off; the code was organized in a cleaner way. As a result, even though you just completely re-did how screens are loaded, you only had to make relatively minor changes to two functions.

Summar y

This chapter covered pre-loaders at great length. Some of the key points include the following:

Pre-loaders provide feedback for long loads. They also provide a way for follow-up code to run right after a load has finished.

The two main pre-loaders available are the MovieClipLoader class and the combination of the Loader and ProgressBar components. Additional control can be obtained by creating your own pre-loader.

The Loader and ProgressBar components result in an additional 32 KB being added to your project. As a result, they are not appropriate for the initial download of the main content. They are better suited for loading additional content on demand once the main content has downloaded.

Two approaches to structuring a site are the monolithic movie approach and the split-up movie approach. The first sacrifices longer initial load time for greater response time, and is simple to implement. The second approach lowers initial load time and makes for easier-to-expand projects, but adds some complexity to the project.

225

Chapter 8

Exercises

1.Modify the following code to add an onLoadError event handler that alerts the user when an error occurs. It should deal separately with an incorrect URL error and a download timeout error. Refer to the built-in Flash help panel under ActionScript 2.0 Language Reference ActionScript Classes MovieClipLoader Class for details on the onLoadError event.

Here’s a hint: upload the file exercise1Trailer.swf, available in the Chapter 8 folder of the downloadable source code, to a remote server. Change the URL in the loadClip() method to point to the file on your server.

this.createEmptyMovieClip(“movieHolder”, this.getNextHighestDepth()); this.createEmptyMovieClip(“progressMovie”, this.getNextHighestDepth()); progressMovie._x = 60;

progressMovie._y = 120; progressMovie.createTextField(“percentDoneLabel”, progressMovie.getNextHighestDepth(), 40, 0, 100, 20);

var loadListener:Object = new Object(); loadListener.onLoadStart = function(contentHolder:MovieClip)

{

progressMovie._visible = true; contentHolder._visible = false; contentHolder.stop();

};

loadListener.onLoadProgress = function(contentHolder:MovieClip, ; bytesLoaded:Number, bytesTotal:Number)

{

var percentDone:Number = bytesLoaded / bytesTotal * 100; showProgress(percentDone, progressMovie);

};

loadListener.onLoadComplete = function(contentHolder:MovieClip)

{

progressMovie._visible = false; contentHolder._visible = true; contentHolder.play();

};

var contentLoader:MovieClipLoader = new MovieClipLoader(); contentLoader.addListener(loadListener); contentLoader.loadClip(“exercise1Trailer.swf”, movieHolder);

function showProgress(percentDone:Number, progressBarHolder:MovieClip) : Void

{

var barWidth:Number = percentDone;

progressBarHolder.percentDoneLabel.text = String(Math.ceil(percentDone))+” %”; progressBarHolder.clear();

// Draw a border progressBarHolder.moveTo(0, 20);

226

Pre-Loading Movies

progressBarHolder.lineStyle(1, 0x666666); progressBarHolder.lineTo(100, 20); progressBarHolder.lineTo(100, 30); progressBarHolder.lineTo(0, 30); progressBarHolder.lineTo(0, 20);

// Draw the bar progressBarHolder.moveTo(0, 20); progressBarHolder.beginFill(0xCCCCCC, 100); progressBarHolder.lineTo(barWidth, 20); progressBarHolder.lineTo(barWidth, 30); progressBarHolder.lineTo(0, 30); progressBarHolder.lineTo(0, 20); progressBarHolder.endFill();

}

2.Modify exercise 1 to use the ProgressBar component instead of using the showProgress() function.

227