Feb 20, 2012
Posted on Feb 20, 2012 in Hints and Tips | 10 comments
In today’s (Very) Quick Tip, you’ll learn how to solve the common problem of flickering or tearing. This is a horrible effect in Flash where bitmaps flicker as they are updated, or appear to tear into two images (as in the thumbnail).
What Causes These Issues?
In a nutshell: tearing occurs when Flash draws information from two different frames to the screen at once. In the thumbnail image above, you can see how this might look when panning across an image of a tower; the bottom part of the image is from one frame, while the top half is from the next. When watching this in motion, you would only see it for a fraction of a second at a time, but it would still be noticeable.
This is commonly solved using “V-sync” (vertical synchronization), which stops the video card drawing anything to the screen until the screen’s next refresh cycle. However, Flash has really poor support for V-sync, because the frame rate of Flash Player is different to the desktop’s vertical refresh rate, meaning that objects that have a lot of height will be hit hard by tearing. This is true even if Flash’s frame rate is equal to the desktop vertical refresh rate, as they are still not synchronized.
Now you may be wondering: Why don’t Adobe fix this problem? The reason is that Flash uses a timeline, and changing the frame rate consequently changes the speed of playback. If you made a game or image gallery running at 60 frames per second and the desktop vertical refresh rate was more than 60 frames per second, you would either have slight stuttering (if you left the movie at 60fps), or would have to play the movie back faster to sync with the desktop. For most content, this wouldn’t be recommended at all!
This is a problem game developers have wanted Adobe to fix for a long time but it’s obvious that there are issues with them doing so. So, at the moment, we developers have to come up with creative ways to solve this problem ourselves. There is no easy way to fix it on all computers, but as most monitors have a refresh rate of 59.9 or 60 then you can set the frame rate to 60 to solve it for most users. However, this requires more processing power and could slow your application down.
The best way to solve this at the moment is fairly simple and easy to do. It doesn’t fix the underlying cause, but it does help reduce the amount of tearing as much as possible.
How Can I Reduce Tearing?
Hardware Acceleration Level 1: Direct is the key to helping the tearing problem. This can be set by opening the HTML file where your SWF is embedded and editing the parameters for the Flash object.
The flag you want to set is wmode: "direct". This line goes in the ‘params’ section of your HTML code. That’s it, that should help dramatically reduce the tearing. If you want to know why, look at Adobe’s page on hardware acceleration. It explains a little about both levels of hardware acceleration. For even more information, check out this in-depth article.
Anything Else?
Yes; another thing to mention is that, the more objects you have on the screen, the more obvious the tearing will become. Smaller items are not usually affected by V-sync issues, but items on the screen which are large make it very obvious, so keeping the number of large objects to a minimum is a good idea.
Also, using bitmapData.lock() and bitmapData.unlock() is recommended and has helped some people with this problem. Locking a BitmapData object stops any bitmaps from being redrawn until it is unlocked, which is a good idea if you need to make multiple changes between frames. To learn more, take a look at this blog post.
Conclusion
You can do a few things to help reduce tearing but you cannot eliminate it completely. Reducing the amount of large objects, setting wmode:"direct" and using bitmap locking are the best ways to help reduce tearing.



View full post on Activetuts+
Feb 3, 2012
Posted on Feb 3, 2012 in Hints and Tips | 10 comments
In this Quick Tip, we’ll discuss the confusing AS3 error 1203, “no constructor found”, which crops up without provocation and is rather unfortunately worded. We’ll examine the scenario in which it will appear, and how to fix it.
Step 1: An Obligatory But Somewhat Useless Description of Error 1203
First, here is the language of the error:
1203: No default constructor found in base class flash.display:BitmapData.
It’s difficult to break this down into plain English. So let’s next move on to a scenario that produces this error.
Step 2: A Busted Project
You can find this project in the download package, in the folder “busted“. It consists of the following (which you can use to re-create this project if you prefer a hands-on approach):
- A FLA named Busted.fla. It is empty, but is linked to the document class described next.
-
A document class named Busted.as. This extends Sprite and simply creates an instance of the class described next, and adds it to the stage.
The contents of the class are as follows:
package {
import flash.display.*;
public class Busted extends Sprite {
public function Busted() {
var bmp:Bitmap = new Bitmap(new BustedBitmap());
addChild(bmp);
}
}
}
The BustedBitmap class extends BitmapData, and so we use it to feed a Bitmap object, which is then added to the stage.
-
Another class file named BustedBitmap.as. As mentioned previously, this extends BitmapData, and its purpose is to be a BitmapData that automatically supplies itself with some Perlin noise. Its contents are:
package {
import flash.display.*;
public class BustedBitmap extends BitmapData {
public function BustedBitmap() {
perlinNoise(100, 100, 2, 1024, false, false, 7, true);
}
}
}
So, in the BustedBitmap constructor, we call perlinNoise() and thus we automatically have something interesting in the pixel data, so we can see something right away when displaying on the stage.
Now, go ahead and test the movie. You will get Error 1203, pointed at line 4 of BustedBitmap.as. And line 4 is…
public function BustedBitmap() {
Step 3: What’s All This, Then?
So what happened? The big thing to keep in mind is that we’re writing a class that is a subclass of another class (BitmapData in this case). Also keep in mind that when a class is instantiated, the constructor is called as part of the “new” process.
If you do not actually write a constructor, ActionScript will imply one for you. It will look like this:
public function [NameOfClass]() {
}
Where “[NameOfClass]” will match the name of your class.
Similarly, if you write a subclass, and don’t call super() in it, then ActionScript will imply that call for you, as well. It will look like this:
public function [NameOfSubclass]() {
super();
// Other explicit code in subclass constructor
}
Note that it happens on the first line, and is simply a call to super with no arguments.
Finally, we get to the root of the problem. If your subclass omits an explicit call to super, and your superclass’s constructor has required parameters, then your implicit call to super does not supply the required parameters. You’d think that an argument mismatch error could catch this, but consider that since there isn’t any code actually written to make the mismatch, ActionScript can only complain that the lack of a default constructor.
In our example, BustedBitmap extend BitmapData, which has a constructor defined in the documentation as so:
BitmapData(width:int, height:int, transparent:Boolean = true, fillColor:uint = 0xFFFFFFFF)
The first two parameters are required, and we’re not supplying them.
Step 4: It’s as Simple As…
The solution is, once you understand the problem, extremely simple. You need to explicitly call the super constructor, at least if there are required parameters. In other words, in our BustedBitmap class, this following highlighted line will fix the problem:
package {
import flash.display.*;
public class BustedBitmap extends BitmapData {
public function BustedBitmap() {
super(600, 400);
perlinNoise(100, 100, 2, 1024, false, false, 7, true);
}
}
}
And that will do it.
As a teachable moment, I’d like to add that, when extending another class, it’s generally a good idea to include the explicit call to super. Even if there are no parameters at all, required or otherwise (as in Sprite or MovieClip), an explicit call can declare intention and awareness of the nature of the subclass. More practically, explicit calls give you an opportunity to run some code prior to the call to super, which may be helpful in certain situations.
Step 5: …And That Is All
Yet another error demystified; the challenge for this one is that the real cause of the error is quite buried. Once you become handy with a shovel, though, the fix is easy enough.
Thanks for reading, and be ready for more debugging tips.



View full post on Activetuts+
Jan 30, 2012
Posted on Jan 30, 2012 in Hints and Tips | 10 comments
In this Quick Tip, I’ll show you how and why the Bubble Sort algorithm works, and how to implement it in AS3. You’ll end up with a class that you can use in any Flash project, for sorting any array.
Final Result Preview
Here’s a simple demo of the result of the bubble sort algorithm:
Of course, this SWF doesn’t prove much on its own! Grab the source files and you can edit the input array yourself.
Step 1: Creating the BubbleSort Class
As this algorithm will be used more than once, it’s a good idea to create a class for it, so that we can easily use it in any AS3 project:
Set up a basic Flash project, and inside the project folder create a file BubbleSort.as. (We will create a tester file here too, so we can test it.)
If you dont know how to work with classes please check this tutorial: How to Use a Document Class in Flash.
We wont need the constructor, so get rid of it! Your class should look like this:
package
{
public class BubbleSort
{
}
}
Step 2: How the Algorithm Works
This algorithm is not the fastest or most efficient method of sorting a series of numbers, but it is the easiest one to understand.
This image sums it up; at every stage, each pair of numbers are compared, starting from the end, and swapped (by means of a “spare” temp variable) if they are in the wrong order.
Once all consecutive pairs have been checked, this guarantees that the number at the start is the largest number in the sequence; we then repeat, checking every pair of numbers apart from the number at the start. Once all consecutive pairs have been checked, we know that the first two numbers in the sequence are in the correct order (they are the largest and second-largest). We keep going until we’ve put every number in the correct order.
It’s called the “bubble sort” because, on each pass through the array, the biggest number “floats” to the top of the array, like a bubble in water.
Lets start writing the code. We’ll call the main function bsort():
package
{
public class BubbleSort
{
public function bsort(arr:Array,sortType:String):Array
{
var temp:String;
if(sortType.toLocaleLowerCase() == "descending")
{
}
else if(sortType.toLocaleLowerCase() == "ascending")
{
}
else
throw new Error("You have a typo when Calling the bsort() function, please use 'ascending' or 'descending' for sortType!");
return arr;
}
}
}
The function gets two parameters. The first parameter, arr, will be the array to be sorted; the second paramter, sortType will be used to decide if the user wants the array to be sorted in ascending or descending order.
In the function we declare a temp variable which will hold the elements of the array in case we need to swap the two elements. You may wonder why it is not a Number. It’s because our class will be able to handle String arrays too, sorting them alphabetically; we can convert numbers to strings and back again, but we can’t convert strings to numbers and back again, so we use a String for this variable, just to be safe.
We use an if-else block to split our code into two branches, depending on which direction the user wants to sort in. (If the user does not provide a valid choice, the program will fire an error.)
The difference between the code in either branch will be just one character: either < or >.
Let’s write the algorithm. We start with the descending part:
package
{
public class BubbleSort
{
public function bsort(arr:Array,sortType:String):Array
{
var temp:String;
if(sortType.toLocaleLowerCase() == "descending")
{
for(var i:uint=0; i < arr.length; i++)
{
for(var j:uint=arr.length-1; j > i; j--)
{
}
}
}
else if(sortType.toLocaleLowerCase() == "ascending")
{
}
else
throw new Error("You have a typo when Calling the bsort() function, please use 'ascending' or 'descending' for sortType!");
return arr;
}
}
}
As you can see, we’re using nested for loops. One goes from the first element to the last element of the array; the other goes backwards.
Let’s inspect the inner “j” loop first. As the earlier diagram shows, we begin by comparing the last two elements of the array, which are arr[j-1] and arr[j] (in the first iteration). If arr[j-1] is less than arr[j] they need to be swapped.
In either case we subtract one from j (through the “j--” call in line 131), which changes which pair of numbers will be compared on the next loop.
j starts at a value of arr.length-1, and ends with a value of 1, meaning that the inner for loop checks every consecutive pair, starting with the last pair (where j equals arr.length-1) and ending with the first pair (where j equals 1).
Now let’s look at the outer “i” loop. Once all the pairs have been checked and swapped as necessary, i is increased (through the “i++” call in line 129). This means that, the next time round, j will start at arr.length-1 again, but end at 2 this time – meaning that the first pair in the sequence will not be checked or swapped. This is exactly what we want, since we know that the first number is in the correct position.
As it goes on, eventually there will be only two elements that need to be checked in the inner loop. Once they’re done, we know we’ve sorted the array!
Here’s what that looks like in code:
for(var i:uint=0; i<arr.length;i++)
{
for(var j:uint=arr.length-1; j > i; j--)
{
if (arr[j-1] < arr[j])
{
temp = arr[j-1];
arr[j-1] = arr[j];
arr[j] = temp;
}
}
}
And the algorithm is ready!
Now we can use the same logic to create the ascending sort:
We need only to change the comparison operator in the if block of the inner loop:
package
{
public class BubbleSort
{
public function bsort(arr:Array,sortType:String):Array
{
var temp:String;
if(sortType.toLocaleLowerCase() == "descending")
{
for(var i:uint=0; i<arr.length;i++)
{
for(var j:uint=arr.length-1; j > i; j--)
{
if (arr[j-1] < arr[j])
{
temp = arr[j-1];
arr[j-1] = arr[j];
arr[j] = temp;
}
}
}
}
else if(sortType.toLocaleLowerCase() == "ascending")
{
for(var k:uint=0; k<arr.length;k++)
{
for(var l:uint=arr.length-1; l > k; l--)
{
if (arr[l-1] > arr[l])
{
temp = arr[l-1];
arr[l-1] = arr[l];
arr[l] = temp;
}
}
}
}
else
{
throw new Error("You have a typo when Calling the bsort() function, please use 'ascending' or 'descending' for sortType!");
}
return arr;
}
}
}
Step 3: Creating the Tester Application
Create a new flash file, tester.fla, in the same folder as BubbleSort.as. Create two dynamic text fields, name one input_arr and the other one output_arr.
After creating the appearance, we must create and link the document class.
Create a file Tester.as and link this to tester.fla
Now we can finally use our class in the Tester.as:
package
{
import BubbleSort;
import flash.display.MovieClip;
public class Tester extends MovieClip {
private var bs:BubbleSort = new BubbleSort();
public function Tester() {
var ar:Array = [5,7,9,8,1,3,6,2,4,5,0];
input_arr.text = ar.toString();
ar = bs.bsort(ar,"descending");
output_arr.text = ar.toString();
}
}
}
In this line, we call the bsort() function of our variable bs (which is an instance of BubbleSort):
ar = bs.bsort(ar,"ascending");
This function returns an array, so we can assign this as the new value of our original input array.
Save everything and try your work out.
Conclusion
In this tutorial we created a function to help us sort an Array. We could improve the efficiency; for more on that, you can read Wikipedia – Bubble Sort
If you really wish to see how fast this algorithm is compared to the other options (like quicksort), take a look at sorting-algorithms.com.



View full post on Activetuts+
Jan 20, 2012
Posted on Jan 20, 2012 in Hints and Tips | 10 comments
In the previous Quick Tips, we’ve looked at collision detection – essentially, detecting that two shapes have overlapped. Now, we’re ready to look at collision reaction: making something happen due to a collision. In this Quick Tip, we’ll look at the reactions of reflection and sliding.
Final Result Preview
Let’s look at the end result we’ll achieve at the end of this tutorial. Each Flash demo has a restart button; click it to reset the position of the circles at the top of stage.
The first demo shows off reflection:
The second shows sliding:
Step 1: The Reflection Formula
I’ve run through this topic several rounds with students, and experience has taught me that the head-on approach of explaining vector math to freshers results in blank faces and confused minds. So instead of putting up a Math lecture here, I shall refer those who are interested in investigating this topic further to Wolfram’s page on reflection.
Here, I shall simplify my explanations with diagrams below. Recall vector addition:
Now, observe the diagram below. A is the circle’s velocity before a collision, and A’ is its velocity after the collision.
It’s obvious that A' = A + 2 V(Ap), where V(Ap) represents the vector with a magnitude of Ap, in the direction of the left normal. (You can see this by following the dashed lines.)
In order to obtain V(Ap), we shall project A onto the left normal.
Step 2: Implementation
Here comes the ActionScript implementation of reflection. I’ve highlighted the important parts. Line 67 – 69 is to calculate V(Ap) (v_leftNormSeg2) and line 70 implements the formula. You may refer to the full Actionscript under Reaction1.as.
(You should recognise most of the code from the previous Quick Tip.)
private function refresh(e:Event):void {
for (var i:int = 0; i < circles.length; i++) {
//calculating line's perpendicular distance to ball
var c1_circle:Vector2D = new Vector2D(circles[i].x - x1, circles[i].y - y1);
var c1_circle_onNormal:Number = c1_circle.projectionOn(leftNormal);
var c1_circle_onLine:Number = c1_circle.projectionOn(line);
//if collision happened, undo movement
if (Math.abs(c1_circle_onNormal) <= circles[i].radius
&& line.dotProduct(c1_circle) > 0
&& c1_circle_onLine < line.getMagnitude()){
//redefine velocity
var v_leftNormSeg2:Vector2D = leftNormal.clone();
var leftNormSeg2_mag:Number = Math.abs(velos[i].projectionOn(leftNormal))
v_leftNormSeg2.setMagnitude(leftNormSeg2_mag);
velos[i] = velos[i].add(v_leftNormSeg2.multiply(2));
}
circles[i].x += velos[i].x;
circles[i].y += velos[i].y;
}
}
Step 3: An Interactive Version
Take note that this reflection formula is applicable to line of any gradient. In fact, you can program your line to be adjustable at runtime and see it reflecting circles like the Flash presentation below. Just click and drag near the lower end of the to redefine it.
Step 4: Sliding Along Line
The concept of sliding along the line is almost identical to reflection. Observe the diagram below.
The vector of slide is A' = A + V(Ap) with V(Ap) representing a vector with magnitude of Ap. Again, to obtain Ap we shall project A onto the left normal.
Note that as the circle is sliding along the line, it is colliding with the line. Of course, collision points differ among circles that collide onto line, so some overlap the line as they move along it. This doesn’t look good, so we’ll have to reposition them.
Step 5: Redefine Location
Now, let’s reposition circles on the line while maintaining their contact with line. Refer to the diagram below.
An important variable to calculate is the projection of A along line. The radius of circle is readily available, and we already have B, so we can form the vectors of B and C. Adding the two will give us A, the exact location to reposition circle. Simple!
The Flash presentation below is coded according to the mentioned idea. But there is one problem: the circles jitter along the line.
There’s one final detail we missed. Diagram above shows magnitude of C should be equivalent to radius of circle. However, this will position circle back above the line. Since there’s no collision detected there, the circle will fall onto the line again, which in turn will flag the collision detection and cause the circle to be repositioned.
This cycle will repeat until the is past the end of the line segment; the visual result of this cycle is the jittering effect.
The solution to this problem is to set the magnitude of C to slightly less than the radius of the circle: (radius of circle - 1), say. Observe the Flash demo below which uses this idea:
Step 6: Implementation
So here’s the important ActionScript snippet for sliding along the line. I’ve highlighted the important parts.
private function refresh(e:Event):void {
for (var i:int = 0; i < circles.length; i++) {
//calculating line's perpendicular distance to ball
var c1_circle:Vector2D = new Vector2D(circles[i].x - x1, circles[i].y - y1);
var c1_circle_onNormal:Number = c1_circle.projectionOn(leftNormal);
var c1_circle_onLine:Number = c1_circle.projectionOn(line);
//check for collision
if (Math.abs(c1_circle_onNormal) <= circles[i].radius){
//check if within segment
//if within segment, reposition and recalculate velocity
if (line.dotProduct(c1_circle) > 0 && c1_circle_onLine < line.getMagnitude()) {
//repostion circle
var v_lineSeg:Vector2D = line.clone();
v_lineSeg.setMagnitude(c1_circle_onLine);
var v_leftNormSeg1:Vector2D = leftNormal.clone();
v_leftNormSeg1.setMagnitude(circles[i].radius - 1);
//v_leftNormSeg1.setMagnitude(circles[i].radius); //uncomment this to check out the error: jittering effect
var reposition:Vector2D = v_lineSeg.add(v_leftNormSeg1)
circles[i].x = x1+reposition.x;
circles[i].y = y1+reposition.y;
//redefine velocity
var v_leftNormSeg2:Vector2D = leftNormal.clone();
var leftNormSeg2_mag:Number = Math.abs(velos[i].projectionOn(leftNormal))
v_leftNormSeg2.setMagnitude(leftNormSeg2_mag);
var veloAlongLine:Vector2D = velos[i].add(v_leftNormSeg2);
circles[i].x += veloAlongLine.x;
circles[i].y += veloAlongLine.y;
}
//if not in segment (e.g. slide out of segment), continue to fall down
else {
circles[i].x += velos[i].x;
circles[i].y += velos[i].y;
}
}
//No collision in the first place, fall down
else {
circles[i].x += velos[i].x;
circles[i].y += velos[i].y;
}
}
}
Conclusion
Hope this is helpful. Thanks for reading. Prompt me if there are questions, and I’ll see you next Quick Tip.



View full post on Activetuts+
Jan 19, 2012
Posted on Jan 19, 2012 in Hints and Tips | 10 comments
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:
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!



View full post on Activetuts+
Page 2 of 21«12345...1020...»Last »