Category Archives: Actionscript 3.0

Why you keep getting a computeSpectrum Security Error

Probably one of the worst and most frustrating bugs.

Turns out computeSpectrum will NOT work if ANOTHER Flash is using audio. Meaning if you have a Flash that using SoundMixer.computeSpectrum one of those super annoying security sandbox runtime errors will pop up on the browser if YouTube, GMail, or any other Flash using audio is opened.

The fix? There is no fix. No, security.allowDomain won’t work. No, placing crossdomain.xml all over your server won’t work either. The only thing one can do is catch the error (or use areSoundsInaccessible()) and have something else happen in between. This bug is especially annoying for game developers like me who are working on a game that uses the computeSpectrum to generate content…

Grrr… So annoying.

Encourage Adobe to fix this by voting for it.

Why doesn’t System.Capabilities class have browser property?

Can someone explain why Adobe put in the feature:

trace(Capabilities.os); // gets the operating system

and not something like

trace(Capabilities.browser); // gets the browser... this property doesn't exist unfortunately...

On a game project I’m working on, the game uses key combinations such as CTRL+Z and CTRL+Y for certain features. Unfortunately, combo keys using CTRL key don’t work in Internet Explorer (but they do work in other browsers). What I want to do is detect if the user has IE, then change the key combinations to SHIFT+Z and SHIFT+Y. The only way to determine the browser is by using a server side language or Javascript to pass in the browser into Flash… grr….

Does anyone know if there’s a way to use ExternalInterface to send the keys? I don’t want to depend on Javascript being on a page or specific Flash vars be sent to the user… but I may have to do so.

Update 10/17/08:

I found a way to detect for IE.

Capabilities.playerType; //Returns ActiveX if in IE. 

A string that indicates the type of player. This property can have one of the following values:

  • "StandAlone" for the Flash StandAlone Player
  • "External" for the Flash Player version used by the external player, or test movie mode..
  • "PlugIn" for the Flash Player browser plug-in
  • "ActiveX" for the Flash Player ActiveX Control used by Microsoft Internet Explorer

AS3 EventManager 1.23: cleanUp method added

A major reason why some users of my EventManager class may see more memory leaks being shown than actual memory leaks is because EventManager stores all the listeners in a dictionary. If we remove a display object then technically (if weakReference is set to true) the listeners are removed for the DisplayObject and its children. Until today, EventManager required coders to manually remove every listener they created with EventManager even if Adobe’s GC actually removed them.

As much as I like the listeners being auto removed, I feel it’s better in practice to manually remove them so you know what’s going on while you code. If you always depend on that to happen then you might find yourself with memory leaks.

I never thought to actually have EventManager check each object to see if it’ll trigger the Event EventManager says it has. Therefore, I added cleanUp which will go through all of the listeners and remove the ones that don’t trigger anymore. This new method means that the EventManager should be more accurate in what’s going on (especially if you call a deepTrace now). It won’t work all the time of course (multiple listeners in one object will still be reported as a leak unless garbage collection takes care of it or you use EventDispatcher’s removeEventListener to remove them).

Anyway, check it out.

EventManager Class Update

Hate keeping track of event listeners?

Wish you had removeAllListeners()?  Wish you had removeAllListeners(EventDispatcherWithABunchOfListeners)? Wish you could remove all listeners that targetted a specific function?

A while ago I posted a class I wrote to handle actionscript 3 listeners.

I updated EventManager.as today to by default set weakReference to true and to always add the listener (if you used it before it might break code that didn’t declare the last parameter).

The class has come in handy in so many projects and makes code much nicer. It’s especially useful for destroying all the listeners of an external SWF…

Find the latest version here.

Note that the class doesn’t have full support for listeners with useCapture specified… but who really uses those anyway?

AS3 Primitives

*Edit: I have found that I am wrong about the following (as shown from the comments). In AS3, numbers are in fact placed in their wrapper classes. My interpretation are wrong. You can keep read the following if you want to know how it DOESN’T work. Basically what I describe is how Java works. AVM2 doesn’t do this, it wraps everything as an object… Sort of strange as there are performence gains using primitives.

I read a post recently that asked whether AS3 Number objects are actually treated as objects in AS3.

Number, int, etc are primitives. Just like in Java, these types have their Object class associations in case you want to create instances and call various methods that come with the Number class. For example, the Number class has functions like toFixed for number precison and accuracy.

The concept of primitives are sort of confusing to newer programming as they go against object oriented programming. In fact, in Smalltalk, one of the first OOP languages, EVERYTHING is an object. The +, -, *, etc are treated as “messages”.

In Smalltalk, since everything is an object and has messages passed, you have to specify the function for “+” and “-“. Primitives in higher level languages don’t have that just for this reason. You don’t want to have to write the code to add two numbers together do you? The concatanation syntax for Strings is also “+”. Notice how “-” is not properly handled with Strings while it is with Numbers… 

Also, in terms of an ideological argument, Number can be said to be the lowest form to describe an object. Think of the composition property of object oriented design. Everything is made of objects that are made of objects that are made of objects… There are theoretically an infinite amount of layers in-between.  Object oriented design is the practice of selecting certain layers and abstracting the rest. But at the very core, every object has to be made up of primatives (more specifically, since Strings can be represented as numbers). Think of any class you’ve ever programmed. The properties will always have either primatives or other objects. If you recurisvely loop through other objects they will all also be made up of primatives (unless they have no properties at all… that’s sort of an anomoly and bad programming design dependant on “isA” relationships… so I’m going to avoid that tangent).

Primitive types are the building blocks. Just like materials are made from atoms… you can’t really go lower than Numbers in describing an object. Additionally, primitives are passed by VALUE rather by reference.

Here’s another post I wrote a while back that went a little deeper into this concept.

AS3 EventManager Class: removeAllListeners

I heard about a class that Grant Skinner wrote called Janitor that was supposed to help keep track of listeners, but I couldn’t find it. Consequently, I wrote my own “EventManager” class for a gaming project I’m working on which keeps track of Event listeners in a project.

As all Actionscript 3 developers know, one of the biggest annoyances is keeping track of listeners and ensuring objects are collected in memory. This class does a lot of that for you, and even has a method removeAllListeners which has different filters. So let’s say some listener keeps calling a function, you can remove all listeners that point to that function. Or let’s say you want to remove ALL key listeners.

Here it is:

*EDIT 9/30/08: EventManager Updated. Click here to get it.

For example, let’s say you have something like so:

var obj:MovieClip = new MovieClip();
var obj2:MovieClip = new MovieClip();
obj.addEventListener(Event.ENTER_FRAME,Test,false,0,true);
obj = obj2; obj.removeEventListener(Event.ENTER_FRAME,Test); // Does NOTHING!

Test will still be called every frame! Even though weak reference is set to true and there are no more references to obj! This is not good! But with EventManager…

var obj:MovieClip = new MovieClip();
var obj2:MovieClip = new MovieClip();
EventManager.addEventListener(obj,Event.ENTER_FRAME,Test,false,0,true,true); // last parameter actually adds the listener, see documentation in class of why this last parameter exists.
obj = obj2; // Now we have a bunch of options, any of the bottom lines would work EventManager.removeAllListeners(null,Event.ENTER_FRAME); // will remove all Event.ENTER_FRAME listeners
EventManager.removeAllListeners(null,Event.ENTER_FRAME, Test); // will remove all Event.ENTER_FRAME listeners that call Test
EventManager.removeAllListeners(null,null, Test); // will remove all listeners that call Test EventManager.removeAllListeners(); // will remove all listeners

The only problem with the class is that this version does not distinguish useCapture events… But big deal. Maybe I’m naive, but how often does anyone actually set useCapture to true?

Anyway, if this class gets a lot of attention I’ll put it as open source on Google Code. Then someone else can add in functionality for useCapture.

This class was such a pain to code. AS3’s Dictionary is the only sure fire way to index objects as objects (as Array uses the result of toString() for indexes), but because (for some reason that’s beyond me), Adobe decided not to have a length property in Dictionary, my life was made very difficult. There might be some bugs, but based on my initial tests everything seems to be working fine. I wonder how Grant’s Janitor class is compared to mine. I really couldn’t figure out any other way to write the function definitions for EventManager.addEventListener and EventManager.removeEventListener (having actuallyAddListener and actuallyRemoveListener as the last parameter). I wish AS3 had a way to get the memory location value of an object. Something like Object.toMemoryString or something. That way Arrays could be used and the Object.toMemoryString value (which would be unique for every single object) could be used as keys.

If you decide to use this class, please let me know so I know my work hasn’t been in vain!

Astro (Flash Player 10) Beta Released!

Here are some highlighted features of the new player (a list by Adobe can be found on their labs page)

  • Adobe has finally made noise (read introduction material parts 1, 2, 3 by Adobe Engineer Tinic Uro). Keith Peters (who is one of the lucky few to have a version of Adobe’s upcoming authoring tool) has posted a sample application showing dynamic sound.
  • Native 3D effects! Interesting to see how Away3D and Papervision will react. While the native 3D addition will be great for vector graphics, Astro doesn’t support texture mapping or 3D model importing from 3rd party software while current open source projects like Away3D and Papervision do.
  • Multi-column layouts/tables for textfields.
  • Ability to change bitrates for streaming video on the fly.

Here are some demos by Adobe.

My reaction: After a survey showed some astronomical 98% of online videos use the Flash Player, Adobe seems like they are trying to cater to those needs. There are HUGE additions to video with Astro, and while I don’t see video portals such as YouTube or Google Video using the native 3D engine (unless it’s for some visualization), I do see web designers smiling as they can now deliever unique features for their clients. It’s only a matter of time before a 3D navigation using video is released by some design firm for a client.

There are also some… somewhat random… additions to the Flash Player. For example, inverse kinematic support with a new “Bones” tool. Is this feature really necessary? What was wrong with just using one of the many 2D physics engines?

Unfortunately, Adobe hasn’t released LiveDocs yet… But that will come soon. Understandable since much of the syntax is subject to change.

I wonder how long now before AS4 and the new ECMA features…

Jacobi Algorithm in AS3

Recently, my “Calculus for Computer Science” teacher assigned the following problem.

So to complete this assignment, I decided to use Actionscript 3 and Flash. A friend of mine and I at Georgia Tech are developing a complex open source matrix library called as3matrix, and we were planning on implementing Jacobi to find eigenvectors of a MxM matrix anyway, so we decided to just apply it to our library.

The Jacobi algorithm is pretty straight forward. It’s impossible to use a formula to find the eigenvalues of a matrix larger than 5×5 because there is no equation solver for equations to that degree. So let’s say you have an 6×6 matrix. To find the eigenvectors, the Jacobi algorithm creates a smaller 2×2 matrix inside that matrix, diagonlizes that, then reapplies it to the matrix.

So what the program I turned in does, is generates a random 5×5 matrix. The program then begins to diagnolize the Matrix using the Jacobi algorithm. Then the program attempts to try diagnolizing the Matrix using the Jacobi method but this time ignoring sorting to solve the 2×2. Obviously, sorting is much faster since it ensures the 2×2 can be diagnolized (since the corner entries will be the largest absolute value of the matrix).

So anyway, here’s how the process works in our as3Matrix library. The jacobi() method computes one interation, while diagonalize() continues the jacobi method until the Off (the sum of the square of off-diagonal elements) is less than 1e-10.

First, take the matrix A. Find the i,j element in the matrix that have the largest absolute value. Create a 2×2 matrix from the i,j elements where a = i,i ; b = i,j ; c = j,i ; d = j,j . This step was probably the hardest part because I kept mixing up the i’s and j’s! Quite annoying when you accidently flip them…

Next, take that 2×2 matrix and diagonalize it. The formula for the eigenvalues that the library uses for 2×2 matrices is:

var L1:Number = ( (a+d)/2 ) + Math.sqrt( 4*b*c + ((a-d)*(a-d)))/2;
var L2:Number = ( (a+d)/2 ) – Math.sqrt( 4*b*c + ((a-d)*(a-d)))/2;

For the eigenvectors, I use a nice trick found by Harvard professor Oliver Knill. I then normalize (which is something Oliver’s page fails to mention) the eigenvectors. Combining the eigenvectors to {u1,u2}, I now have my matrix U.I take that matrix and embed it into the identity (of size of the original, original matrix).  I call that matrix G. Then D is Transpose(G)*A*G.

Then outside of the method I check if the Off(D) is < 1e-10. If so, then I consider the Matrix diagonalized!

Here are the results of Jacobi (with sorting) vs Theoretical Bound and Jacobi (without sorting) vs Theoretical Bound. Since AS3 doesn’t have an LN function, I just used the change of base formula (log(X)/log(2)). I hard coded log(2) to optimize the code.

A couple of random 5×5 matrix sample:

After running 100 random 5×5 symmetric matrics through the Jacobi algorithms, these were the average number of iterations for each:

Average Sorting = 25.11
Average no Sorting = 102.94

Sorting is clearly the best method.

Anyway, you can browse/download the as3matrix library here. Check out the TestJacobi.as in the trunk.

A Few Things You May Not Know About CacheAsBitmap

cacheAsBitmap is a feature in Flash (since Flash 8) that tells the Flash Player to store a movieclip of vectors into one static instance in memory. It’s a great way to boost the performance of your Flash.

But I’m writing about how to use cacheAsBitmap (you can just google that).

Some things you may never knew about cacheAsBitmap.

  • With the exception of changing position, if a movieclip animates with cacheAsBitmap set to true, performance will slow down. This is because the Flash Player must recalculate the vectors and reload the Bitmap instance into memory. Moving x or y doesn’t change the vectors of the movieclip and thus will not affect performance.
  • cacheAsBitmap is automatically set to true whenever a filter is set on a movieclip.
  • A movieclip moving with cacheAsBitmap set to true, the movieclip will probably not animate smoothly. Unless the displacement values are round numbers, the movieclip will seem to move in a zig zag.

Example:

clip.cacheAsBitmap = true;
clip.onEnterFrame = function() {
this._x += 1;
this._y += 1;
};

Will look fine…

clip.cacheAsBitmap = true;
clip.onEnterFrame = function() {
this._x += 1.5; // Decimal displacement makes things shaky
this._y += 1.5;
};

Won’t.
Just take a look at the following example… Is the red dot shaking or is it just me? Maybe it’s scared of the blue dot.

Flash Player 9r45 Weird Behavior

So I was working on the sequel to Boomshine this week, and for some bizarre unexplainable reason, the file SWF perfectly in Flash Player 9 r45; however, if I dropped down to Flash Player 9 r28 (or anything lower), the Flash wouldn’t work at all!

I looked at the change log for r28 to r45 released by Adobe. These are the four I could find:

New ActionScript 3.0 components for Flash CS3 Professional do not function correctly in versions prior to Flash Player 9.0.45.0.

Well, I am using some CS3 components, but Adobe doesn’t say they should crash, only that they do not function correctly.

Runtime Shared Libraries (RSLs) exported for ActionScript 3.0 generate a runtime security error. (195395)

No runtime errors for me…

Display objects instantiated by the playhead entering a frame because of a gotoAndStop command (or similar action) incorrectly process actions on frame one. (189490)

This is something that I don’t quite fully understand. However, just to be safe, I move all my code from frame 1 to frame 2.

flash.text.TextField.getCharBoundaries returns a rectangle that is offset to the left by 2 pixels for fields that are created using the Flash CS3 Professional text tool. (193249)

Not applicable in my situation.

As you can imagine, this was painful to debug. I downloaded Flash Switcher Extension for Firefox by Alessandro Crugnol which allows you to switch Flash versions on the fly inside a browser. The only negative side to this is that Firefox has to restart every time you switch flash versions.

After investigation and frustration, I finally figured out the problem.

In Flash 8 and Actionscript 2.0, to get around the preloading linked movieclips and objects properties, you had to place an instance of the object on one of the frames and uncheck Export to First Frame from the linkage properties menu. This ensured that the assets would load after frame 1 rather than before it. Meaning that you could create a preloader to load the assets.

If it still doesn’t make sense, imagine creating a 5 frame flash. In the first frame you have your preloader code.

onEnterFrame=function()
{
var percLoaded:Number = getBytesLoaded()/getBytesTotal();
trace(Math.floor(100*percLoaded));
if (percLoaded >= 1)
gotoAndStop(5);
}

Now import your favorite picture (larger the better) into the library. Put it in a movieclip, and export the movieclip with the linkage identifier MyPic. Make sure you keep the Export in First Frame checked.

Put the following code on frame 5.

attachMovie("MyPic","MyPic",1);

Run the flash and you should see 100 in the trace action and your picture on the screen. Now try simulating the download, you’ll still see that the preloader will only show 100. This is because the preloader frame is actually loaded after the picture is loaded.

To reverse this, go back to the library panel and uncheck Export to first frame. Run the flash, and you’ll notice the picture doesn’t show up anymore! That’s because the picture wasn’t loaded into Flash memory before the frame that wanted to display it.

Now place the movie clip on the stage on frame 3. Run the flash, in simulated download mode, and you’ll notice your preloader is now working fine and tracing from 0-100 a few times before going to frame 5 and showing the picture. Now that you put the image on frame 3, frame 3 has grown in memory size and loaded the movieclip, meaning that after the preloader finishes, you can attach the movieclip on runtime. Pretty nifty.

Now I told you that story to tell you this story. Flash 9 has changed completely. You can no longer uncheck the Export to First Frame, else the SWF will simply not work – with Flash Player 9 r28.

DisplayObjects aren’t the only things affected, sound won’t load either unless it’s loaded before the first frame.

Check out the attached source for an example. It will work perfectly with Flash Player 9r45, but with anything lower, it won’t.

Maybe I’ll submit this to Adobe so that they can add it to the change log?

Download the FLA that won’t work with Flash Player 9r28 and below…

-Danny