Quick Tip: Use FZip to Open Zip Files Within AS3

In this tutorial I will introduce you to FZip, an AS3 Library that lets you open zip files inside your Flash projects. This can save a lot of bandwidth; in this tutorial we will load an 2.5MB zip file which contains 9.3MB worth of assets.


Final Result Preview

Let’s take a look at the final result we will be working towards. Click here to open a SWF that will in turn load a zip file full of images, and display them in a tiled grid.

(The blurring visible on some icons is due to Flash automatically attempting to scale them up to 32x32px, even though those particular images are 16x16px.)


Step 1: Getting the Library and Zip Archive

You will need to grad a copy of the FZip library from Claus Wahlers’ github .

Extract the library. Inside the src folder there is a folder named “deng”; copy this folder to the folder where you will store your FLA.

Next we need a zip archive to work with. I choose the WooFunction icon set, available for free from woothemes.com .

Save this to the same directory where you will store your FLA.


Step 2: Create New Flash Document

Open a new FLA and give it the following properties:

  • Size: 550x400px
  • Background Color: White

Save this as fzip.fla .


Step 3: Add Components to Stage

Go to Window > Components and drag a TileList component to the stage.

Under “Component Parameters” set the following properties:

  • columnCount : 16
  • columnWidth : 32
  • rowCount : 8
  • rowHeight :32

Give the TileList the instance name imageTileList , and set the following properties in the “Position and Size” panel:

  • X: 20
  • Y: 68
  • W: 100
  • H: 100

Next select the Text Tool and make sure the following properties are set in the “Character” panel:

  • Size: 50pt
  • Color: Black

Now drag a TextField onto the stage, and give it the instance name imagesLoaded . Make sure the TextField is set to “Classic Text” and “Dynamic Text”, respectively, and set the following properties:

  • X: 54
  • Y: 161
  • W: 454
  • H: 60

Step 4: Create new AS3 Document

Go to File > New and choose “Actionscript File”.

Save this file as Main.as .


Step 5: Package, Imports and Constructor

Inside Main.as add the following:

private function demonstrate():void
package  {

	import flash.display.MovieClip;
	import deng.fzip.FZip;
	import deng.fzip.FZipFile;
	import flash.display.Loader;
	import flash.net.URLRequest;
	import flash.events.*;
	import  fl.controls.TileList;
	import fl.data.DataProvider;

	public class Main extends MovieClip {

		public function Main() {
			setupZip();
		}
	 }
}

Here we imported the classes we will need for this tutorial, and set up the Main() constructor function.


Step 6: Add Variables

Define the following variables above public function Main() :

private var zip:FZip; // Instance of FZIP class
private var numFiles:int = 0; //Number of files
private var numFilesLoaded:int = 0; //Number of files loaded
private var done:Boolean = false; //Done processing zip archive?
private var tileListDp:DataProvider = new DataProvider();//Data provider for the TileList

Here we add some variables we will need throughout the tutorial. See the comments for their usage.


Step 7: setupZip()

Add the following new function below Main() :

private function setupZip():void{
	zip = new FZip();
	zip.addEventListener(Event.OPEN, onOpen);
	zip.addEventListener(Event.COMPLETE, onComplete);
	zip.load(new URLRequest("wootheme.zip"));	//change this to match your zip file's URL
	imageTileList.visible = false;
}

Here we create a new instance of the FZip class, add two event listeners, and load our zip file. Last, we set imageTileList to be invisible (We don’t want it to show until all the images from the zip have loaded).


Step 8: onOpen()

Add the following new function beneath the setupFzip() function you entered above:

private function onOpen(evt:Event):void {
	addEventListener(Event.ENTER_FRAME, onEnterFrame);
}

This function gets called when the zip archive has been opened. Here we add an ENTER_FRAME event listener.

Step 9: onComplete()

Add the following code new function beneath the onOpen() function you entered in the step above.

private function onComplete(evt:Event):void {
	done = true;
}

This function gets called when there are no more files to process from the zip archive.


Step 10: onEnterFrame()

Add the following beneath the onComplete() function you entered above. This function will be triggered every frame after the zip file has been opened:

private function onEnterFrame(evt:Event):void {
    //Only load 32 files per frame, to save processing power
	for(var i:uint = 0; i < 32; i++) {
		// any new files available?
		if(zip.getFileCount() > numFiles) {
			//yes so get it
			var file:FZipFile = zip.getFileAt(numFiles);
			// is this a png in the icons folder?
			if(file.filename.indexOf("woofunction-icons") == 0 && file.filename.indexOf(".png") != -1) {
				var loader:Loader = new Loader();
				loader.loadBytes(file.content);
				tileListDp.addItem({source:loader});
				numFilesLoaded++;
			}
			numFiles++;
		} else {
			// no new files available
			// check if we're done
			if(done) {
				removeEventListener(Event.ENTER_FRAME, onEnterFrame);
				removeChild(imagesLoaded);
				imageTileList.visible = true;
				imageTileList.dataProvider = tileListDp;
			}
			//Exit the Loop
			break;
		}
	}
	imagesLoaded.text = numFilesLoaded + " Images Loaded";
}

Here’s the meat of the code.

Since this is running every frame, we’ll place an artificial restriction on the number of files within the archive that we deal with at once. That’s the purpose of the for-loop.

zip.getFileCount() reveals how many files are in the zip; numFiles stores how many files we’ve dealt with so far . So, line 5 checks whether there are still more files to deal with.

If there aren’t any files left, we skip to line 17 and just do some basic clearup: remove the ENTER_FRAME listener, remove the “loading” text field , make the tile list visible, and link it to the data.

If there are files left, we get the next one in our list using numFiles as an index. We then check whether it’s a PNG from the icons folder; since we know the structure of the zip beforehand, we can cheat and just check whether the file’s name and path contains “woofunction-icons” and “.png”.

To get the image from the zip and into a DisplayObject, we can use a Loader. This class is often used to load an image from a URL , but here we’re using its loadBytes() method to get the data from the ByteArray created by FZip.

Since Loader extends DisplayObject , we can just add it straight to the TileList’s DataProvider. Then we increment both numFilesLoaded and numFiles .

Why do we have two integers to keep track of how many files are loaded? Well, numFiles keeps count of all the files we’ve examined from the zip, whereas numFilesLoaded keeps count specifically of the image files that we’ve loaded into the DataProvider . It’s the latter variable that we use to update the “loading” text at the end of the function.


Conclusion

FZIP is an amazing little utility to save some loading time and bandwidth. I hope you’ve found this tutorial useful, and thanks for reading!

如果你感兴趣

分享该文章


相关微博 共有()条
请登录后评论
已发表评论数()
评论加载中