AS 3.0 Components and Web Services in Flash CS3
December 4th, 2007 | View Comments
If you use components a lot, one thing you might notice about Flash CS3 is the number of components available when you create an ActionScript 3.0 based project. For comparison, the following screenshot shows you the number of components you have access to by default in AS 2.0 and AS 3.0 projects:
Having fewer components is fine. There is certainly a cost associated with creating and testing components – especially brand new ones using AS 3.0. The frequency each component was being used might also have played a role in determining which got cut. Unfortunately, that does not help the many of you who want to create AS 3.0 projects and actually used the components that got axed such as Menu or Tree.
I am generally not a huge fan of components because of their ability to inflate your file size and limit (easy) customizability. To workaround those issues and for simulating missing components, with some ingenuity, you can re-create a lot of the functionality found in many of these visual components yourself. You have full control over how your component looks, and the file size is often significantly less. Sure, in most cases, your code will not be as clean or as well-separated and layered across many classes like a built-in component coming from Adobe or a great component vendor, but you and your visitors can live with the results.
Web Services are a Different Ballgame
The tough part is living without those components you cannot create yourself. One of my most frequent Flash CS3 related e-mail question revolves around the use of web services in an AS 3.0 project. This is one of those components that did not make it across the bridge into the AS 3.0 world created by Flash CS3. Creating your own web services functionality is difficult for the average designer and developer, and getting it to work across many scenarios is even more difficult.
If you rarely use components in the drag-drop-modify scenario and prefer working with the actual classes instead, you are out of luck also. There aren’t any built-in AS 3.0 classes in Flash CS3 that allow you to connect to a web service and communicate data. My earlier post relating to programmatically connecting to a web service only works on AS 2.0 projects. While Flex does support (and includes) web services components and classes, I don’t know if it is possible to use those classes in an AS 3.0 project created in Flash CS3.
Help is on the Way….In the Meantime!
The lack of web service components in Flash CS3 for AS 3.0 projects is something that Adobe is aware of, and according to a post by John Dowdell in July 2007, was going to be addressed soon with a document that was in the final stages of review.
Until that document appears, I have heard good things about wellconsidered’s Flash CS3 Web Service Class for AS3 projects. What’s even nicer is that the author is more than gracious enough to accept feedback on any issues you encounter in your real-world use of this component.
Cheers!
Kirupa
Debugging: Go Beyond Trace() in Flash CS3 / AS3
August 20th, 2007 | View Comments
When debugging your Flash application, my favorite way to take a peek at some data is by using the trace() function. In case you are not familiar with trace, it is a simple function that prints to the screen any text-based data. Almost all languages provide trace-like functionality, and some that you can relate to are printf, Console.WriteLine, System.Out.println, etc.
The nice thing about trace() is that it is a quick way for displaying text-based information from a variable. Therein lies the problem. I mentioned that it is “a quick way for displaying text-based information”. Not all data that you are interested in displaying is text-based. For example, you may be interested in viewing the contents of a Dictionary. You can’t simply do trace(DictionaryObject) and expect to see something meaningful.
This problem becomes more apparent when tracing the contents of something we have all used, an array. As long as your array contains strings, doing a trace on the entire array displays the string-based values. For example, let’s say you have the following code:
- var stringArray:Array = new Array(“What’s”, “up”, “doc?”);
- trace(stringArray);
When you run the above code, you see the following displayed in your Output Window:
That’s great. Of course, you won’t have text-based information stored in your array all the time. To continue my previous example, you could store a series of Dictionary objects, XML nodes, etc. These are all objects that have internal methods that return text-based values, but when they are placed in an array, accessing those internal methods is difficult. Micromanaging a single object is much easier than dealing with a collection of those same objects in an array.
For example, take a look at the following code where I create objects of type Person and send them to our array:
- var mysteryOne:Person = new Person(“Sherlock”, “Holmes”);
- var mysteryTwo:Person = new Person(“James”, “Watson”);
- var mysteryThree:Person = new Person(“Mycroft”, “Holmes”);
- var peopleArray:Array = new Array();
- peopleArray.push(mysteryOne);
- peopleArray.push(mysteryTwo);
- peopleArray.push(mysteryThree);
- var mysteryTwo:Person = new Person(“James”, “Watson”);
When you trace your peopleArray, the following is what you see:
The above output is not quite as informative, for you don’t actually know any specifics about the data your array is storing beyond the type. The reason for the generic information is, like I’ve mentioned several times, our trace function only prints text-based information. Tracing an object returns only its type name, which in our case, is Person. It is times like this where some of the debugging features in Flash CS3 come in handy.
Breakpoints and the Debugger
An alternate approach to using trace is by using breakpoints. Breakpoints mark a line in your code, and when played back in the Flash Debugger, allow you to analyze all of the data Flash is juggling at that particular point. To see this in action, let’s say I specify a breakpoint at the line where I am about to add my third Person object to my peopleArray:
The breakpoint is designated by the red circle that is displayed to the left of the line number. Once the breakpoint has been specified, go to Debug | Debug Movie (Ctrl + Shift + Enter) to display the Flash Debugger (click on below thumbnail for larger image):
When your application hits the line marked with the breakpoint, your Debugger will stop and allow you to analyze all public data stored at that point in the application’s life. The part we are most interested in can be found in the Variables panel:
In the Variables panel, you see all of the variables currently initialized and stored in memory. Beyond just seeing the variables, you can expand any objects and access any of the public variables/properties/etc. that get exposed:
Notice that I expanded our Person objects, and as shown in the above image, internally our Person objects contain public variables called firstName and lastName. These variables display the data I passed to the constructor when I initialized my Person objects in the code I posted earlier. Anyhoo, let’s address the problem displaying non-string data in arrays.
When you expand the peopleArray node, we see the two array cells as well as the length property. Looking deeper, each array cell contains our Person objects mysteryOne and mysteryTwo. Like before, you can expand your mysteryOne and mysteryTwo Person objects to see what its firstName and lastName values are:
As you can see, using the debugger with well-placed breakpoints provides you with greater access to interesting data beyond what the trace function can show you. The debugger is especially useful when you are trying to view data that is layered, as in, the information you want is stored in a series of nested objects and variables as was the case with our Person objects located in our Array.
Cheers!
Kirupa
Interview: I (and others) Answer Questions About Flash
August 8th, 2007 | View Comments
A few months ago, I was requested by Mark Angeletti from search-this to answer five questions about Flash both from a technical as well as a non-technical/business point of view. You can read my answers as well as those by well known developers Bartek Drozdz (Fantasy Interactive) and Keith Peters (bit-101) in the following location: http://www.search-this.com/2007/08/08/3-flash-masters-answer-5-flash-questions/ (my answers are the ones flagged in red)
For easy access to just my answers, I have pasted them below:
- What do you see as Flash’s key asset(s)?
The main asset of Flash is how easy it is to go from launching the IDE, creating the content, and publishing the content to the web for others to access. As long as the user has the Flash plug-in installed, the content displays consistently with little variation across browsers, platforms, etc. If the user does not have the Flash plug-in, downloading and installing it is very straightforward.
It is this, usually hassle-free, experience that makes Flash unique when compared to a host of other development platforms. This focus on simplicity on the deployment side help it to gain a lot of trust both with regular users and designers/developers who want an easy way to create and distribute interactive content.
- What do you think is Flash’s biggest weakness?
Macromedia (and now Adobe) spent and continue to spend a great deal of effort trying to make the lives of designers easier. With each subsequent release, the integration between Flash and other applications such as Fireworks, Photoshop, etc. sees marked improvements. Beyond integration with other designer applications, features centering round drawing become much better also.
Despite the improvements made for designers, I feel that Flash could offer a lot more for developers. The introduction of ActionScript 3 is great, but the tools for writing and debugging the code are very rudimentary. Even with Flash CS3, the code editor provides very limited functionality for developers who are accustomed to features found in other popular IDEs.
- If you could change one thing about Flash what would it be?
The one thing I would change is how the components are loaded in Flash. Right now, using components greatly increases the file size of an animation. A blank Flash SWF file is around 40 bytes, and adding, for example, a simple Button component inflates the file size to 15kb. Creating your own simple button from scratch with Up, Over, and Down states takes up less than 300 bytes. The Button component isn’t alone, for you experience similar file size increases when using the other components also.
Part of the reason is that large parts of these components are defined and stored within the SWF itself. My solution to this problem would be to store the component parts in the Flash Player instead with the SWF, storing only the component parts the user modifies. With this change, adding components will no longer increase the SWF file size as rapidly as it does now.
While the SWF size will decrease, this solution will increase the Flash Player’s file size. In the end, I think the benefit of having smaller SWF files sizes when using components offsets the gain in file size found in the one-time download of the Flash Player.
- Has Flash’s popularity peaked?
No, I do not think the popularity of Flash for end-users has peaked. A few years ago, nobody outside of a few individuals would have guessed how extensively Flash would be used to deliver videos on the web. As you are reading this right now, I am sure somebody out there is working on something else (maybe using Flex or Apollo) that will push Flash in a new direction.
To take a broader view by looking at developers, unlike in the past, the RIA space has gotten more interesting with technologies ranging from Silverlight, JavaFX, OpenLaslo, JavaScript, etc. competing for user and developer attention. Developers now have a choice in picking the right tool for the right job, and the tool chosen may or may not be based on Flash.
I believe this increased competition gets a lot of developers familiar with non-ActionScript languages to target the web. This is not a zero-sum game, so while the percentage of RIA projects using Flash might decrease, the quantity of developers who target Flash will continue to increase at the same rate as it has since Flash was first introduced. To look at it another way, Flashers in the future will have a smaller piece of a much, Much, MUCH larger RIA-flavored pie.
- What will Flash look like in 3 years?
In three years, I think Flash will feature hardware graphics acceleration. Right now, even the lowest-end computers feature graphics cards capable of breezing through fairly complex visuals, but Flash’s lack of hardware acceleration leaves such functionality beyond the reach of developers.
Ideally, Flash will combine some of the best elements of the Shockwave Player. The Shockwave Player features hardware acceleration by default with support for DirectX and OpenGL, and the Xtras extensibility model allowed developers to provide more functionality to users on an as-needed basis.
Thanks to Mark Angeletti for giving me the chance to talk more candidly about Flash. There is some extra discussion of this on a kForum thread covering the interview.
Cheers!
Kirupa
Creating Animated Button Rollovers
June 17th, 2007 | View Comments
Almost all modern frameworks such as .NET and Flash provide default UI controls/components such as Buttons that you can use. These components are provided for several reasons. One of the main reasons is to provide a consistent look and feel across applications. Another reason is to make your life easier. UI components are fairly complex to develop even if the functionality they provide seems fairly simple.
If you want to create your own UI control, it is fairly easy to make them look cool. Giving them the functionality provided by a default UI control is time-consuming, and sometimes, tricky. One common feature that the star of this post, the friendly Button control, provide is rollover and click states.
The following image shows you the various states of an example button I created:
You have the Default state that shows your button as it looks normally. When you move your mouse cursor over the button, the button is then in its Mouse Over state. Whenever your button state changes because of an action you took, such as moving your mouse over the button, the button will change to indicate that action. In my example, the button changes its color based on what you are doing to the button. When you moved the mouse cursor over the button, its color changes from Blue to Yellow. To continue on, when you press down on the button, your button changes into a Green color that I specified.
When using default UI controls, the Default, Mouse Over, and Mouse Down states are provided for you. When you create your own buttons, though, you’ll have to design the various button states yourself. Creating simple changes that occur on mouse over and mouse down is easy. You only need to design the Default, Mouse Over, and Mouse Down states, tie them to the various mouse events, and you are done! IDE’s such as Blend/Visual Studio for WPF and Flash for Flash make creating these simple rollovers easy.
In this post, I will skip describing how to create the simple rollovers and, instead, describe how to create the more time-consuming animated button rollovers. The main distinction between a normal rollover and an animated rollover is, as the description implies, the animation. In an animated button rollover, you have transitions that work between the various button states. Instead of changing the color of the button suddenly, you have a quick transition that animates the color change instead. This clearly looks more spiffy, and spiffy is good.
For example, when you hover over our button, it will gradually transition from its blue color to its yellow color:
Beyond just the transition from Default to Mouse Over, you will also need to have another transition going from the Mouse Over state back to its Default. This is something you do not have to worry about in the simple rollovers. In an animated rollover you have to undo an earlier transition such as our earlier Default -> Mouse Over transition:
The opposite of Mouse Over is known as Mouse Out, so we trigger the Mouse Out state and go back to Default when your mouse moves away from the button hit area. The reason we reverse our transition from earlier is because your button will look odd if there is a transition going into a button state but there isn’t a transition when you undo or exit a button state.
Therein lies what makes creating animated button rollovers time-consuming. You need to explicitly define the various transition states and their converse. Here are some common ones that you might want to implement in your own buttons to maintain consistency with other applications:
- Default -> Mouse Over
- Mouse Out -> Default
- Mouse Over -> Mouse Down
- Mouse Up -> Mouse Over
The colors indicate how the various button looks/states are related. For example, even though Mouse Down and Mouse Up are different events, how your button looks is actually the same. As you can see, there are still only three different looks for your button as in the simple case. Because we are throwing transitions into the mix, we still have to design/code twice the number of transitions to go both ways between the three states.
Both Flash and WPF do not make it easy (relative to the simple, non-animated rollovers) to create the above transitions. In WPF, you can create multiple storyboards to specify the various transitions and trigger the appropriate storyboard as necessary. In Flash, you can create multiple movie clips and play the appropriate movie clip depending on the mouse event that was fired. That is the easy part.
Much of your time, though, will be spent creating one animation and reversing it for the opposite case. Like I mentioned earlier, one animation will involve going from the Default state to the Mouse Over state. Your next animation will be the opposite where you go from the Mouse Over / Mouse Out state back to the Default. You repeat this process for the other states also. These tasks would be made much easier if either WPF or Flash supported reversing an animation easily, but as far as I know, they don’t outside of having to delve into the code. If they did, you would only create one animation and play it in reverse for its opposite state. That means that you will create three transitions for the three button states for animated rollovers just like you would for the simple rollovers.
Unlike in the past, there is a stronger movement today towards integrating designers and developers into a project. Part of the integration means that there is a distinction between the UI and the actual application logic with designers and developers working in their own field of expertise. When you begin to write code for reversing a transition, you begin to interfere with what the designer is primarily responsible for. If you are a one-man (or woman) design team, you can do whatever you want. If you are part of a larger team with distinct individuals responsible for designing the UI and logic of your application, it is best to discuss these overlaps first.
Cheers!
Kirupa
Scanning Files using DFS + Going Between Languages
June 12th, 2007 | View Comments
A long time ago, I wrote an article outlining how to use Depth First Search (DFS) to navigate a tree structure. The tutorial’s code and explanations are based on ActionScript 2.0 syntax. In this post, I will discuss porting the tutorial’s DFS implementation to C# and discussing some things to consider when going between languages.
Scanning Files in your Hard Drive
Using the ActionScript code in the tutorial, I wrote some C# code that allows you to scan files in your hard drive:
- public List<string> StartSearch(string path)
- {
- DirectoryInfo[] directoryListing = new DirectoryInfo(path).GetDirectories();
- List<string> openList = new List<string>();
- List<string> closedList = new List<string>();
- List<string> folderNames = new List<string>();
- openList.Add(path);
- while (openList.Count != 0)
- {
- List<string> openList = new List<string>();
- string currentPath = openList[0];
- openList.RemoveAt(0);
- try
- {
- openList.RemoveAt(0);
- DirectoryInfo[] neighbors = new DirectoryInfo(currentPath).GetDirectories();
- for (int i = 0; i < neighbors.Length; i++)
- {
- for (int i = 0; i < neighbors.Length; i++)
- DirectoryInfo currentFolder = neighbors[i];
- openList.Add(currentFolder.FullName);
- folderNames.Add(currentFolder.Name);
- openList.Add(currentFolder.FullName);
- }
- closedList.Add(currentPath);
- }
- catch (UnauthorizedAccessException e)
- {
- catch (UnauthorizedAccessException e)
- //Some folders will not be accessible
- }
- }
- return folderNames;
- }
- }
- class Program
- {
- }
- static void Main(string[] args)
- {
- FolderSearch foo = new FolderSearch();
- List<string> folderNames = foo.StartSearch(“C:\\Program Files”);
- //foreach (string f in folderNames)
- //{
- // Console.WriteLine(f);
- //}
- List<string> folderNames = foo.StartSearch(“C:\\Program Files”);
- }
- }
The main difference between what is displayed above and presented in the tutorial is use of try/catch statements in the C# version. Beyond that, the syntax and style are very similar, and I used none of the AS or C#-specific syntax to make the code more compact or nicer.
Going Between Languages – The Good, the Bad, the Ugly
Using a more generic syntax provides a major advantage. It makes moving between languages more easy. While the class names of certain core libraries might be different, the basic functionality provided by almost all modern runtimes (Flash and .NET in this case) are similar.
With that said, just because you can use generic syntax does not mean you always should. While behind the scenes many runtimes make optimizations based on the code you have written, sometimes it is best to explicitly write code with performance in mind. Using generic syntax aids in readability and portability, but it might not aid with performance. You will have to determine for yourself the level of readability, portability, and performance you are going to achieve with your code.
For tutorials on this site, I emphasize readability and portability, but for actual applications, I emphasize readability and performance. These three characteristics are not mutually exclusive, especially if going between two higher-level languages. What is exclusive is optimizations that change how your application behaves.
Sometimes, porting an application between languages can be ugly. The above code, if run on a directory with many sub-directories, will tax the processor heavily. Flash does not expose thread manipulation functionality to the developer. In Flash, you could use timers and intervals to allow the message queue to process other requests to avoid freezing your application, but that is not fun. With a .NET-based language or Java, you can use threads to make your application more responsive, but you will not be able to port your code to Flash.
Conclusion
The main takeaway from this post is that it does not take much effort to write code that makes porting between languages easy. The difficulty lies in making sure your final implementation is great. Your users are more interested in how your application works instead of how it was written or the hacks you used to get it working. If searching a directory freezes the application for several seconds, your users are not going to appreciate that you ported AS code into C#. Instead, your users will be frustrated that the application does not behave well.
To re-use a phrase used earlier, just because you can do something does not mean you always should. If you are going to do something, be sure you are aware of the consequences of your actions.
Cheers!
Kirupa
Event Handlers and Dynamic Movie Clips in AS 3
May 20th, 2007 | View Comments
One of the major changes in AS3 is how event handlers are used. My upcoming tutorial and this blog post will cover how to use event handlers to work with dynamic content. For a more thorough coverage of event handlers, check out Trevor McCauley’s (senocular) excellent article [adobe.com] on this very topic. There is also a printable doc version [senocular.com].
What is an Event Handler?
An event handler allows you to trigger certain actions based on a particular event. In most cases, you have a listener that is on the lookout for something interesting, and when something interesting occurs, it calls a function to deal with the interesting event. In AS3 (like languages such as C# and Java), you distinctly have to add a listener to an object, specify the event the listener should be on the lookout for, and have a function that performs an action.
For this post, I am going to modify some code from my Displaying Library Content tutorial. In the tutorial, your application displayed blue circles taken from the library. The extensions covered in this post allow you to click on one of those circles (MouseEvent.CLICK) and cause them to animate (Event.ENTER_FRAME).
Let’s look at the code for doing that:
- function Main() {
- for (var i:int = 0; i < 40; i++) {
- var newCircle:BlueCircle = new BlueCircle();
- var randomValue:Number = Math.random()*1;
- var originalX:Number = -100+Math.random()*500;
- var originalY:Number = -100+Math.random()*400;
- newCircle.x = originalX;
- newCircle.y = originalY;
- newCircle.startXPos = originalX;
- newCircle.scaleX = newCircle.scaleY = randomValue;
- newCircle.alpha = 1-randomValue;
- //
- // Dynamically adding a property called speed
- //
- newCircle.speed = randomValue;
- this.addChild(newCircle);
- newCircle.addEventListener(MouseEvent.CLICK, CircleClick);
- }
- }
- Main();
- function CircleClick(event:MouseEvent):void {
- Main();
- //
- // Casting target of event back to MovieClip
- //
- var targetMC:MovieClip = MovieClip(event.target);
- //
- // Add event listener for Enter Frame
- //
- targetMC.addEventListener(Event.ENTER_FRAME, MoveInCircle);
- //
- // Remove event listener for Mouse Click
- //
- targetMC.removeEventListener(MouseEvent.CLICK, CircleClick);
- // Casting target of event back to MovieClip
- }
- function MoveInCircle(event:Event):void {
- //
- // Doing some circle movement
- //
- var targetMC:MovieClip = MovieClip(event.target);
- //
- // The speed property was dynamically added when creating the BlueCircle objects
- //
- var targetMCSpeed:Number = targetMC.speed;
- targetMC.x += 10*targetMCSpeed;
- if (targetMC.x > 500) {
- // Doing some circle movement
- targetMC.x = -100;
- }
- }
It seems like a lot of code, but it really isn’t. Like I mentioned before listing all of the code, there are three main things you need when wanting to use events in AS3. You first need to add an event listener to an object, you then need to figure out what to to listen for, and finally, you need to create a function that does something when the listener finds what it is listening for. The above code contains them all and more!
Adding Event Listener
One area I add an event listener is when I am telling Flash to recognize click events on the circles:
- newCircle.addEventListener(MouseEvent.CLICK, CircleClick);
The dynamic movie clip is called newCircle, and I use the addEventListener function to add a listener to it. I look for click events by checking MouseEvent.CLICK, and when something is found, I call the CircleClick function.
Removing Event Listener
When you add an event listener, it is attached for life to that object. To remove an event listener, you use an approach similar to what you used when adding an event listener. The main difference is that you use the removeEventListener function instead:
- newCircle.removeEventListener(MouseEvent.CLICK, CircleClick);
By removing an event handler, as long as you specify the same arguments for event and function, you undo its corresponding addEventHandler counterpart.
The Listener Function
With addEventListener or removeEventListener, you need to specify a function that is fired. The function you use must take in one (and only one!) argument of type Event, and the return type of the function must be void:
- function MoveInCircle(event:Event):void {
- //
- // Doing some circle movement
- //
- var targetMC:MovieClip = MovieClip(event.target);
- //
- // The speed property was dynamically added when creating the BlueCircle objects
- //
- var targetMCSpeed:Number = targetMC.speed;
- targetMC.x += 10*targetMCSpeed;
- if (targetMC.x > 500) {
- // Doing some circle movement
- targetMC.x = -100;
- }
- }
The above MoveInCircle function is called by our ENTER_FRAME event handler, and notice that it takes in one argument of type Event which I cleverly call event. The return type of the function is also void.
Getting Clicked/Target Object
With dynamic content, you rarely hardcode the names of your content in your code. When you click on a circle in our example, how will you know which particular circle was clicked? You can figure that out in your listener function by using your Event object’s target property:
- var targetMC:MovieClip = MovieClip(event.target);
In the above code, I am creating a new targetMC movie clip object, and I am casting the object returned by event.target to movie clip form. You now have the source of your event in the form of a movie clip, and you can use it like you would any other movie clip.
I hope this brief intro to event handlers helps! Be sure to check out senocular’s tutorial on this topic, and to a lesser degree, my upcoming tutorial that covers the specifics of using event handlers with dynamic content.
Cheers!
Kirupa
Flash CS3′s Publishing to HTML Changes
April 27th, 2007 | View Comments
One of the less publicized changes in Flash CS3 has been the improvements made when publishing your content to HTML. By default, in Flash 8 and earlier, when you specify HTML as a publishing option, two files would be generated – your HTML and SWF files. While the HTML file contained the tags required to play your SWF and worked well out-of-the-box, it had some unresolved issues. The main issue for developers revolved around avoding the dreaded “Click here to activate and use this control” message that affected Internet Explorer users:

To remedy that problem, you often had to use solutions such as my article where you use a third party JavaScript file such as FlashObject to handle embedding the Flash content. Beyond specifying the parameters to your JavaScript file, you needed to specify a div section in your HTML where the Flash content would actually be loaded. While these steps were not time consuming, they still added a few extra roadblocks between you and providing your users with a consistent experience.
Flash CS3′s Changes – Embed and Standards
In Flash CS3, though, a lot of the extra steps needed to publish your content in earlier versions can be avoided. By default, the embed issue is fixed after a publish operation. Unlike the two files generated by Flash versions earlier than 8, the new publish option in Flash CS3 generates three files – the usual HTML and SWF files, but also a JavaScript file:
The JavaScript file fixes the embed issue, and the HTML produced relies exclusively on the JavaScript to display the Flash content. Rest assured that the classic embed/param approach still exists inside <noscript> tags where users who have JavaScript disabled in their browser can still view your content.
While I focused primarily on the embed issue, Flash CS3′s HTML output seems more standards compliant also. Over the years, various 3rd party implementations have been provided to improve the HTML output, and the most common one I noticed was the Flash Satay approach. With CS3, most browsers will see a cleaner version of the code used to display Flash content, but the caveat is that the embed/object/param tags have not disappeareed entirely. If your users do not have JavaScript enabled, the browser will read the information from, what I mentioned earlier, the <noscript> tags which do contain embed/object/param.
Cheers!
Kirupa
AttachMovie, Auxiliary Data, and Dynamic Languages
April 17th, 2007 | View Comments
In my earlier post, I discussed using the Tag element to store auxiliary data to a WPF control. You have similar functionality in ActionScript’s attachMovie function (and others!), and in this post I will explain some of the interesting things about this and what allows it to work the way it does.
Hello AttachMovie
The attachMovie function is used to take content during runtime from your library and display it on your stage. For an in-depth look at attachmovie, the Animating Dynamic MovieClips tutorial will come in handy. AttachMovie, though, does more than just simply displaying library elements on your stage. One interesting feature concerns the arguments attachMovie takes. Among its strictly defined arguments are idName, newName, and depth, but attachMovie also takes an arbitrary amount of loosely defined arguments denoted as initObject:
What the initObject allows you to do is pass in data the newly attached movieclip will have within its scope. The data can be mapped to variables such as the properties _x, _alpha, etc., but the data can also be random variables that the attached movie stores within itself.
For example, let’s look at the following code snippet of a attachMovie function:
- this.attachMovie(“circleMC”,
- “newCircle”,
- this.getNextHighestDepth(),
- {_x:40, _y:50, _alpha:75, kName:“Kirupa”, kColor:“Blue”,
kAge:22}); - “newCircle”,
The main thing to notice in the above snippet of code is the last two lines where the initObject arguments are passed in. The _x, _y, and _alpha properties ensure that the attached movie clip is positioned at 40, 50 with an alpha of 75. More interestingly, the attached movie also stores within its scope the variables kName, kColor, and kAge and their respective values. These variables and their data can be easily accessed by code contained inside the attached movie clip!
What confuses many is this whole idea of having variables stored and passed into some cloud and accessed later. After all, there really is no easy way to know which values have been passed in to your attached movieclip unless you look carefully at the code or add trace statements to your movie clip itself.
To explain it a little better, let’s look at the following image:
In the above image, you have your newly attached movie clip called newCircle storing the variables you passed into it. One thing to note is that these variables are localized to this instance of the newCircle movie clip. If you were to add more newCircle movie clips, they too would contain copies of the kName, kColor, and kAge values. This is almost like what you see with constructors in a strictly OOP language that creates new objects that inherit certain values.
Dynamic Languages Giveth and they Taketh
So, in the end, attachMovie and other similar functions provide a great level of flexibility when it comes to adding your own data to them. This flexibilty comes with the cost of increased time debugging when things don’t work as you expected. For example, for your attachMovie function’s initObject argument, if you accidentally spelled kColor:”Foo” as kColour:”Foo”, your attached movie clip will not inform you of the misspelled kColour variable or point out a reference to a non-existant kColor variable in your attached movie clip. For all it knows, Flash will assume that you meant to create a new variable called kColour instead, and kColor will be populated later using some approach like _root.newCircle.kColor = “Green”. It is extremely difficult to guess what your intentions were, so Flash correctly doesn’t attempt to interfere.
The above advantages and disadvantages are part of the dynamic, non-strict nature of the ActionScript language. Contrasting this you have more strict languages such as the C and Java languages where you cannot use a variable without declaring it, and almost always, declaring a type to go with the variable. The stricter approach makes testing your applications easier, but you lose the flexibilty that you enjoy with a dynamic language. There are good and bad points to both language types, and you’ll see ActionScript 2.0 and 3.0 incorporate some nice features from the more strict languages, and you see good dynamic language support in, for example, the .NET CLR with IronPython, RubyCLR, and others.
WPF Equivalent to initObject
If you are using C#, you can almost emulate the above functionality. The Tag element, as mentioned in my earlier post, takes in an argument of type object, which is great because you can pass in a value of any type to it. The downside is that the Tag element stores only one such object. You can’t pass in a sequence of object variables like you are able to in attachMovie.
To simulate such functionality, you would need to use something like Structs where you create your own datatype that takes in as many arguments as you want. Your Tag element would be set equal to your Structs which, in turn, store all of these values that you want. Consequently, a less efficient solution would be to pass in all of your arguments to a List and pass that List to your Tag element.
Cheers!
Kirupa
Deletes, Loops, and Application Freezes!
March 26th, 2007 | View Comments
In Flash, it is common to stop/remove a current function by using the delete keyword. When you delete a function, though, any work that the function has still left will finish before the function is truly, as the keyword implies, deleted. The reason is that Flash, like most modern languages, runs in a virtual machine that uses some sort of a stack or queue structure for prioritizing what code runs next. For the sake of this article, I will call that structure the call stack. You can learn more about stacks from my earlier article.
When a delete action hits the call stack, depending on what you are doing at that time, the function may be deleted immediately or, what this post is about, the delete action may be left waiting in the call stack until it is executed. To look at this in another way, if your function called some external code that is currently flooding the call stack, your delete action won’t really take effect until your external code has reached an end.
To see the above in action, copy and paste the following code into an empty frame in Flash and run the app:
- function TestEventQueue():Void {
- var count = 0;
- this.onEnterFrame = function() {
- for (i=0; i<20; i++) {
- count += 1;
- trace(“Looping: “+count);
- if (count == 25) {
- trace(“Looping: “+count);
- trace(“Calling delete action at: “+count);
- delete this.onEnterFrame;
- }
- }
- };
- }
- TestEventQueue();
In the pasted code, you have a loop that cycles between 0 and 19 before ending. To make things interesting, the loop is embedded inside an onEnterFrame function. What I am trying to do, is increment a count variable, and when the count variable hits 25, attempt to stop the loop by deleting its parent function – this.onEnterFrame. The behavior I would want is that, after “Calling delete action at…” is called, everything stops.
To see what really happens, let’s look at the Output produced by the above code:
Looping: 1
Looping: 2
Looping: 3
Looping: 4
Looping: 5
Looping: 6
Looping: 7
Looping: 8
Looping: 9
Looping: 10
Looping: 11
Looping: 12
Looping: 13
Looping: 14
Looping: 15
Looping: 16
Looping: 17
Looping: 18
Looping: 19
Looping: 20
Looping: 21
Looping: 22
Looping: 23
Looping: 24
Looping: 25
Calling delete action at: 25
Looping: 26
Looping: 27
Looping: 28
Looping: 29
Looping: 30
Looping: 31
Looping: 32
Looping: 33
Looping: 34
Looping: 35
Looping: 36
Looping: 37
Looping: 38
Looping: 39
Looping: 40
Notice that I make the delete call when the count value is at 25. Ideally, you would expect everything to stop with the “Calling delete action at: 25.” As you can see, though, despite the delete call being made, our loop still continues all the way until it ends when at 40.
The reason behind it goes back to my introductory info on how your call stack works. Despite the delete action being called, the loop has priority in the stack because it is currently in progress and floods the stack with its own actions. Only after the loop has finished does the effect of our “delete this.onEnterFrame” call kick in.
This behavior explains why your application seems to freeze when you are using a loop to process large amounts of data. Actions like a mouse click, menu display, etc. are all stuck on the call stack and don’t execute until after your loop is done sending requests to the stack.
The Solution
There are several simple solutions you can use to avoid the freeze associated with a loop. To break a loop, you can use the break keyword to stop the loop dead in its tracks. You can bypass loops altogether by using enterFrame or setInterval to simulate a loop by specifying code to execute every x frames or every x milliseconds. Both onEnterFrame and setInterval don’t flood the call stack as badly as a loop would, so proper use of them can reduce/avoid application freezes.
Cheers!
Kirupa
Selecting/Highlighting Columns in a DataGrid in Flash 8
February 6th, 2007 | View Comments
The DataGrid component looks very simplistic on the surface, but it has a lot of nice tricks up its sleeve. The only problem is in being able to access those tricks. In previous versions of Flash, if you wanted to fiddle around with a component, you could just edit it directly like a movie clip. In more recent versions of Flash, direct editing has been replaced with a different approach where you can extend the basic functionality using inheritance tricks and overwriting the children with your own classes.
There are several nice APIs provided that allow you to edit components, and this post will briefly touch on the CellRenderer API. The CellRenderer is what is used the DataGrid to help display the data in the cells. In this post, I will describe how to select a vertical column in your DataGrid by modifying your CellRenderer to that of your own movie clip.
To accomplish my goal of selecting a column vertically, I disable many of the default DataGrid functionality. In a default DataGrid, selecting a header cell will cause all of the rows to be ordered based on the values in the column represented by that cell. In my version, when the header cell is clicked, all cells in that column are highlighted instead.
The following is my version of the DataGrid where, as I wanted, columns are highlighted when the header cell is clicked:
You can download the full source code for this by clicking here. The code for this is not too tricky, so I’ve pasted only the interesting portion of the code below:
- //
- // Capturing Mouse Events
- //
- function defineListener() {
- // Capturing Mouse Events
- var listener:Object = new Object();
- listener.headerRelease = function(evt:Object) {
- columnHighlight(evt.columnIndex);
- };
- listener.cellPress = function(evt:Object) {
- // do nothing because ‘selectable’ is set to False
- }
- dataGridMC.addEventListener(“headerRelease”, listener);
- dataGridMC.addEventListener(“cellPress”, listener);
- dataGridMC.addEventListener(“headerRelease”, listener);
- }
- //
- // Highlighting or Un-Highlighting the Columns
- //
- var highlightColumn:Object = new Object();
- function columnHighlight(index:Number) {
- //
- var currSelect:Number = highlightColumn[index];
- if (currSelect == undefined) {
- dataGridMC.getColumnAt(index).cellRenderer = “customColumnStyle”;
- highlightColumn[index] = true;
- } else if (currSelect == true) {
- dataGridMC.getColumnAt(index).cellRenderer = “defaultColumnStyle”;
- highlightColumn[index] = false;
- } else if (currSelect == false) {
- dataGridMC.getColumnAt(index).cellRenderer = “customColumnStyle”;
- highlightColumn[index] = true;
- }
- }
Notice how I attach a listener to the headerRelease action of my DataGrid in the defineListener function. Whenever a header column is pressed and released by the mouse, I intercept the release event, and instead of sorting, call the columnHighlight function that passes in the current column’s index position by accessing the event’s columnIndex property.
The columnHighlight function is where all of the selection and de-selection magic happens. I am allowing for multiple column selections as well as unhighlighting a selected column by clicking on it again. Because each column will either be highlighted or un-highlighted, I need a good way of keeping track of the highlight states of each of my columns. I keep track of the highlight states by simulating a Set using a highlightColumn Object.
The rest of the function largely deals with the three highlight and remove highlight states. The important thing to keep note of is that I define a custom cellRenderer style for the column using the getColumnAt(index).cellRenderer expression:
- dataGridMC.getColumnAt(index).cellRenderer = “defaultColumnStyle”;
The defaultColumnStyle and customColumnStyle references are what you see when you deselect or select a column. In the Library, there are two movieclips called regularText and selectedText. Notice the Linkage Properties for just the selectedText movie clip:

The Identifier is the reference I used in the code earlier, and the AS 2.0 Class is the CustomColumn.as class file that is part of your extracted files:
- class CustomColumn extends MovieClip {
- var txtField:TextField;
- function CustomColumn() {
- }
- function setValue(theValue:String, theItem:Object, selected:String):Void {
- function CustomColumn() {
- txtField.text = theValue;
- //txtField.backgroundColor = 0xE5F4FC;
- }
- }
Notice that our CustomColumn (and our DefaultColumn) classes extend the MovieClip. That is important because the MovieClip object contains numerous methods and properties that are necesary for it to represent a Cell in our DataGrid. If you are familiar with Inheritance in OOP, I simply overwrote the MovieClip’s setValue method with what you see above.
The actual regularText and selectedText movie clips contain the textfield and the solid rectangle with the background fill color. All you need to do is modify the movie clips from the design mode itself to change the appearance of your cells. This all seems a bit roundabout, and in someways it is. It really doesn’t need to be this complicated, but once you get a hang of the CellRenderer API, the roundabout method is actually more elegant and consistent. You write fewer lines of code, and you don’t spend a lot of time reimplementing things that the component already supports.
Cheers!
Kirupa =)





