What Happened to _global? – taterboy
April 13th, 2008 | Filed under: Flash AS2 to AS3
What happened to _global, _root, _level?
I rarely used _root or _level just because some projects would end up getting loaded into other swfs. Sometimes I didn’t know this until halfway through or in the end. So I started using global instead. That way I could still target the main timeline, which is where I would try to keep all my code, without having to worry about root moving somewhere else later. When I built components I would also use global, from time to time, to target them from anywhere in the application being developed.
The best workaround I have come across on the web for storing global variables, is to create a class object and throw all your variables in there. Some great information about this can be found here: http://www.uza.lt/codex/as3-global-object/
A brief simple example is something like this:
package {
public class global{
public static var Vars:Object = new Object();
public static var Arrs:Object = new Object();
public static var _locked:Boolean;
public function global(){
}
}
} |
Notes: If you want to store dynamic variables (ones that are not predefined in the global Class) then you will need to send them to the Object Vars or Arrs (global.Vars.newVariable = “yo!”). Adding and updating arrays can be a little tricky, but I will write a lot more about this in the future. I am working on a watch/listener Class for AS3 that uses some of this functionality.
Like I mentioned earlier, it works great for variables, but not so much for global functions, which is what I used global for the most.
So Let the Griping Begin:
I know it is 3:00 am and you have deadlines. Now is not the time to re-think how to build your application. What in the world was Adobe thinking with AS3 anyway. Flash is a designers/animators tool to build pretty applications right? How in the world do they expect designers to learn this stuff. It took years to get the hang of AS2, now it feels like they have pulled the rug out from underneath us. Plus, now that programmers are the only ones able to program in Flash, expect a bunch of new Flash sites full of ugly stuff that moves.
Before I get too carried away, we should realize things aren’t so bad. Actually they are pretty good.
The Real Answer : Events
AS3 is much more of an Object Oriented Programming(OOP)d language then AS2. We can work around that fact, or we can embrace it. In an OOP mindset, we have to think of our project as made from objects (duh) that are children or siblings of other objects and communicate with each other using events. The new event and child systems are really powerful, it just takes a little getting used to.
When we have multiple objects that need to pass information to a central location, and parent or stage do not work the way _global did, here’s what you do.
Use a Dispatch Event and write a custom event for your application. The cool thing about using events is they can act like _global events used too, but even better. You can call them from anywhere in you app, and you can listen and handle them almost anywhere you need to. This will open lots of doors in the way you can program your apps.

Think legos:
So let’s look at our object model. Like legos or blocks, some pieces have special functionality. like the window or door frame. These pieces are special and will function the same no matter what kind of crazy contraption we build with them.
I want to add some smart home functionality to my door and window. When I close the door, I want the window to close as well. Then when I wake-up and open my window, I want the door to open, to let all that beautiful air and scenery in, because this Lego home will be built in hawaii. Cool!
To show off the global variable class, I will add a locking variable that I can check from both the window and door. Not sure if you need locks in Hawaii, but you sure do where I come from.
package {
import flash.events.Event;
public class globalEvent extends Event{
public static var OPEN:String = "Open";
public static var CLOSE:String = "Close";
public static var UNLOCK:String = "Unlock";
public static var LOCK:String = "Lock";
public var targ:Object;
public function globalEvent(type:String, targ:Object, bubbles:Boolean = true, cancelable:Boolean = false){
super(type,bubbles,cancelable);
this.targ = targ;
}
}
} |
Events:
So let’s put this into practice.
Custom events can have as many arguments as you want and are a very powerful way to communicate to other objects in your application.
One of the arguments in dispatch event is bubbles. Goofy name, but makes sense. This argument tells the dispatcher how far we want this shout-out (or bubble up) to be heard. We can keep it private, within our class or all the way to the root or stage (now we are talking _global baby!). Remember, Events can bubble up, not side to side. I can listen for an event at the container of the object dispatching the event, but not from another sibling or its children.

Better then _global:
In our Event we need to know when something is being opened and closed. So we will add OPEN and CLOSE as our public static vars. When the event is called, it will get dispatched to the super Event class, and we will be able to listen for OPEN and CLOSED events and build handlers to act accordingly. We can add listeners to the container (and above) for our window and door.
The way I used _global in AS2 for something like a navigation system, was to wait for a button press, loop through all the buttons, turning things on and off (rollovers and on-states) and other code. But, what would be even cooler, is if we could listen listen for our events from the siblings. All I have to do is target the listener to the parent of the object, like parent.addEventListener(). Wow!, no more looping through objects. Each object can listen for the event and act accordingly. My movie-clips just got smarter.
package {
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import global;
public class legoClip extends MovieClip{
public var Status:String = "Close";
public function legoClip(){
stop();
init();
}
function init(){
this.addEventListener(MouseEvent.MOUSE_UP,mouseup);
parent.addEventListener(globalEvent.OPEN, getClicked);
parent.addEventListener(globalEvent.CLOSE, getClicked);
}
function mouseup(ev:MouseEvent):void{
if(Status == "Close"){
if(!global._locked){
dispatchEvent(new globalEvent(globalEvent.OPEN,this));
gotoAndPlay("clipOpen");
Status = "Open";
}
}
else{
dispatchEvent(new globalEvent(globalEvent.CLOSE,this));
gotoAndPlay("clipClose");
Status = "Close";
}
}
function getClicked(e:globalEvent):void{
if(e.target != this){
//trace(e.target.name + " / " + e.type + " / " + this.name);
if(e.type == "Close"){
gotoAndPlay("clipClose");
Status = "Close";
}
else{
if(!global._locked){
gotoAndPlay("clipOpen");
Status = "Open";
}
}
}
}
}
} |
Classes:
This app is so simple, writing class files are an overkill right? Wrong, the door and window look different, but the functionality and code to run them are exactly the same. So in this case, I only had to write the code for those two classes, once. One of the down-sides to using class files is it requires export to First Frame. And if you have a loader on the first frame, it will not show up until everything else loads. This kind of defeats the purpose of having a loader, but more about this later (I have some cool loader classes I will share). I like using class files as much as possible, for the sake of re-usability, (Code Once, Use Often, that’s my motto) plus it really is the best way you can animate and do code on a laptop without 2 monitors.
Dispatch Event:
Once everything is loaded and working using dispatch event, our event handlers need to tell out door and window to initiate their animations. The event class keeps track of the object that initiated the event, so we can easily test to see if this is the object that caused the event, if not, then it can respond.
Now we have super-smart clips that can be plugged in or out of our app, and everything will still work. Global does not look so cool any more. It kind of is easier, but not as cool. Now go and build some cool stuff!
|
RSS feed for comments on this post. TrackBack URL
Thanks for the rundown. Public static vars have made my life a lot easier now and then. One thing I’m a little lost on is your custom event. How does a public function in a class that extends Event equal up to a custom event? Plus the whole super thing still eludes me. Nonetheless, I learned some!
Comment by JD — October 12, 2008 @ 9:27 pm
Event is an existing Class (flash.events.Event). A class is made up of a Public Class and a public Function within the class of the same name. This function is the constructor of the class. When the class is called or an new instance of the class is initiated, this public function is executed. Classes can be completely custom or extensions of an existing class.
For this example I wanted to show how you can add properties to the Event class. If we look up Event in the help we can see all the existing properties (public and private), methods and events. We should not modify the Event class itself, so we choose to extend it. When we add “extends Event” we are telling flash we have new class, but instead of rewriting the entire Event class over we want to add to it’s functionality; something that will work better with our application. This is actually called a “sub class”, not technically custom but customized.
The super part is a call directly to the Event class from within our subclass. So when this event is fired, we pass in some data and set our new properties and fire off the parent or super class that has all the functionality we need. Some subclasses do not need to call super “legoClip” class from above.
You can fire a custom event a lot easier then extending the event class. Just put dispatchEvent(new Event(”SOME_EVENT”,true)); Add “,true” if you want the event to bubble up to a higher object, if you just want the event within the object that fired it, then leave it out. You will need to add an addEventListener(”SOME_EVENT”, eventHandler); where ever you want to handle the event, from there you can still get basic event functionality. like event.target and event.type.
Hope this helps.
Comment by taterboy — October 13, 2008 @ 10:11 am