![]() |
Proxy: getProperty and setProperty
getProperty and setProperty are methods used in Proxy classes that are used to manage property access. When a property not defined within a proxy instance is retrieved, getProperty is called to retrieve it. When set, setProperty is used to set it.
As with all methods of the Proxy class, getProperty and setProperty are defined within the flash_proxy namespace (flash.utils.flash_proxy) to prevent conflicts with public. When you override these methods within your own Proxy subclasses, you will want to be sure to use the flash_proxy namespace. The following example, CustomObject, extends Proxy and uses getProperty and setProperty to manage dynamic properties set for its instances. ActionScript Code:
ActionScript Code:
Notice that when getting and setting the foo property, getProperty and setProperty are used to control its ultimate value which is stored within a customProperties defined for the class. Also, since classProperty is not a dynamic variables, instead being one defined for the class, getProperty and setProperty to not apply. |
Flash 9: Display Object Variables and Instance Names
In Flash 9 when you create MovieClip instance on the screen and give it an instance name, you are doing two things:
Flash does this behind the scenes when you publish your SWF to help you manage your movie clips on the screen. It's important to note that this behavior (specifically #2) is not seen with ActionScript. For Example: ActionScript Code:
You can see that neither the instance name (name property) nor the variable to which the new MovieClip created with ActionScript was assigned is referencable through the movie clip in which it was added (my_mc). This is because another_mc was created and added to the timeline dynamically. Flash will only save instance names as variables for movie clips created on the timeline in Flash. If you want to use an instance name to get a MovieClip (or any DisplayObject) instance from the timeline in which it exists, you can use getChildByName(); ActionScript Code:
This will work for all movie clips despite where or how they were located as long as they are within the timeline/movie clip from which getChildByName was used. |
maybe you can do something like
ActionScript Code:
(^thats a question^, i don't know if its that easy to make variables inside of movieclips) |
Quote:
|
Quote:
I was just wondering... if you were going to use a helper class anyway, why would you not just do this: Code:
package testI'm just confused as to why one would want to abstract the EventDispatcher class in a helper. Is that so the helper could extend something else? Nick http://www.velloff.com |
Quote:
It was just an example to show implementation. The helper class was used because MyDispatcher, as the application class, extends Sprite which already makes it an event dispatcher. To keep the example encapsulated in one file, I just used a helper class for the ED implementation. |
XML: XML and XMLList
When working with E4X in ActionScript 3, you deal with 2 kinds of objects, XML (Top level XML) and XMLList (Top level XMLList), both of which are very similar in nature. The big difference between the two is that with XML you are dealing with one specific object (which could potentially contain any number of children) and with XMLList you are dealing with a collection of 1 or more objects. Consider the following:
Code:
// XML:Code:
// XMLList:Unlike the old XML object (now XMLDocument) in previous versions of ActionScript, the XML and XMLList classes do not deal specifically with nodes. Though XML and XMLList can represent a collection of nodes, they can also represent other values such as attributes. Example: ActionScript Code:
Note that attributes are always returned as XMLList instances, even if one value is returned. Consider getting the bar attribute value from the first foo node: ActionScript Code:
Though one element is returned, it is retuned as an XMLList. You can get the XML value of that attribute by returning the first value off of that list: ActionScript Code:
The same applies to XML ActionScript Code:
The XML operations that can return more than one value (nodes, attributes, etc) will return XMLList instances. |
Constants
ActionScript 3 allows you to define constants for your classes. Constants are special kinds of variables that can be defined only once. Typically you'll see constants defined with capital letters. Event.ENTER_FRAME, for example, is a constant.
You define constants in AS3 using the const keyword (const keyword). This is used in place of what would otherwise be var (var keyword). ActionScript Code:
Though constants can't be redefined, if they are object values, methods can still be called that otherwise modify that value. If the constant is an array, for example, Array.push() can be used to add additional elements to that array. As a constant, it just means that the actual value of the variable itself can't be changed. That is to say that array variable will always be that same array and couldn't be defined as another or a new array. ActionScript Code:
|
This all works fine aslong as you dont have strict mode on. If you have the strict mode on it will have a compile error because the constant isnt set at the class initialization. It doesnt even allow it in the constructor funnily enough. The simple answer is to just work with strict mode off :)
|
Quote:
[edit]Ok, doesnt look like it enforces constants at all without strict, and AS3 isnt happy defining constants outside of the declaration so I'm going to keep it there - thanks for pointing that out Deviant1853 :)[/edit] |
Any time Senocular :)
|
duplicateMovieClip Replacement
ActionScript 3 no longer has a duplicateMovieClip method for MovieClip instances (or any DisplayObject instances). Instead, it's suggested that you just create a new instance of the display object you wish to duplicate using its constructor. This, however, is not the same as duplicateMovieClip, and, really, is more like using AS1 and AS2's attachMovieClip. For a more accurate representation of duplicateMovieClip in AS3, consider the following function:
ActionScript Code:
As you can see, this function (duplicateDisplayObject) takes care of making sure a duplicated instance also retains all the information retained by duplicateMovieClip such as transformation, filters, chaching as bitmap, etc. Note: There is currently a bug in Flash Player 9 that causes incorrect values to be returned from the scale9Grid property of display objects. This function compensates for that but may need to be edited should this bug be fixed. Usage: ActionScript Code:
The only thing duplicateMovieClip does that this does not is copy dynamic drawing information. Currently, the graphics object in display objects cannot be duplicated so there is no way to obtain that information for duplicates in duplicateDisplayObject. |
I am quite supprised that Adobe didnt create a non-final method clone() on Object to be overridden for each subclass. I cant see any reason why they wouldnt want to do this :S
|
Proxy: callProperty
The callProperty method of the Proxy class lets you define an action for methods called from Proxy instances. When a method not defined within a proxy instance is called, callProperty is run passing the name of the method called along with an array of the arguments used.
As with all methods of the Proxy class, callProperty is defined within the flash_proxy namespace (flash.utils.flash_proxy) to prevent conflicts with public. When you override these methods within your own Proxy subclasses, you will want to be sure to use the flash_proxy namespace. The following example, CustomObject, extends Proxy and uses callProperty to manage dynamic methods called for its instances. ActionScript Code:
This example uses callProperty to accept generic get and set methods to get and set dynamic "variables" which are stored in the variables object. ActionScript Code:
at first getMyVar returns null since "MyVar" was not yet set (using setMyVar). After being set, getMyVar returns the value it was given through getMyVar. |
Nice work on the duplicateDisplayObject Senocular. I started doing some tests with it... if the constructor of the DisplayObject you are creating has 1 or more required parameters, it fails. Other than that, it seems to work excellent--even with complex Sprites.
~JC |
Creating graphics Copies
Though you can't directly copy graphics created in Sprite and Shape instances' graphics property in ActionScript 3, you can use the Proxy class to create a substitute graphics-like property that will be able to record all methods you use with graphics. Consider the following class, GraphicsCopy:
ActionScript Code:
Instead of using the graphics property for your sprites or shapes, you can use a GraphicsCopy instance that references that object's graphics property. Then, every method used on the GraphicsCopy is recorded by GraphicsCopy but still applied to graphics thanks to Proxy and its callProperty method. Example: ActionScript Code:
ActionScript Code:
Running this will show to green squares, the first drawn using GraphicsCopy (shape1) and the other duplicated from GraphicsCopy (into shape2's GraphicsCopy) using the copy method of that class. Note: Since Proxy classes cannot inherit from Graphics (its abstract anyway), GraphicsCopy instances do not have a Graphics class type associated with them so will not work with methods expecting a Graphics instance. I don't believe there are any inherit methods that use Graphics parameters, but you might make your own or have functions/methods from other sources that do. Using a type of Object or * would allow both Graphics and GraphicsCopy instances to work in that case. |
Quote:
Yeah, for the sake of simplicity I went with the assumption that display objects used would follow with the consistency of Flash display objects and require no constructor parameters :) |
Quote:
|
Quote:
I have got around this problem by creating a singleton MyStage class. It requies on the root of your movie to use: MyStage.init(stage); but other than that it works pretty much how you want. It gives static access to the stage. PHP Code:
The scale mode and the alignment arent nessicary they are just very useful for my needs. |
This worked excellent! Thanks Deviant
|
I tried this code:
ActionScript Code:
But it didn't work. It would appear that the `stage` property of a Sprite isn't set when the Sprite is created. Where does the value of the `stage` property come from, then ? Thanks |
Quote:
A suggestion I've used before was have your application or document class extend a custom subclass of sprite rather than sprite itself. This class could then have that static stage reference which would instantly available since the application/document class is inherently a child of the stage when the SWF starts. On a similar topic, I have a class allowing you to detect when the stage property is available for a display object (i.e. when it has been added to a visible display list) but I was saving that for another tip of the day. If anyone is interested, I can post that one next. |
Hi, Sen and everyone :)
I have a tip request: Singleton in AS3 private is no longer available as constructor's attribute, it makes me just unhappy :bored: I've found two workarounds for this, here about singletons in general and here more concrete. But, there are a lot of discussions and comments about what way is more hackish or useful. I'm confused. The question: Singleton in AS3: best practice, the most common and easy to use (and understand) way, if any... Thanks! |
Quote:
gskinners post is your best approach (private variable usage prefered over helper class). |
Quote:
You mean throwing an error if allowInstantiation == false ? But what about compile time errors? |
TextField.appendText()
The TextField class (flash.text.TextField) in ActionScript 3 has a new method called appendText (flash.text.TextField.appendText()). This method allows you to add additional text onto the end of the text contained within the current text field. This should be used in place of TextField.text += newText since appendText is faster and more efficient.
ActionScript Code:
|
include Directive
ActionScript 3 continues to allow you to include code located in external files within your scripts at compile time using the include directive (include directive).
ActionScript Code:
Notice that the include directive in ActionScript 3 does not contain a # before "include" as it did in ActionScript 1 and 2. Note: You should keep as files included in your ActionScript outside of your class path(s) so that they are not accidentally interpreted as classes. |
Duplicate Variable Definitions
In ActionScript 1 and ActionScript 2, it was possible to define a variable twice in the same scope without error. For example:
ActionScript Code:
This is no longer allowed in ActionScript 3. In ActionScript 3, once you define a variable for a scope, that variable is set for that scope and cannot be redefined as a new variable or as a new type. This, of course, doesn't mean you cannot change the value of a variable. It just means, essentially, that the var keyword should only be used once to declare/define any one variable given any scope. ActionScript Code:
For ActionScript 3, if you need a new type, you will need to create a new variable to contain that type. Also, if you have situations where var was used twice in, for instance, two separate if blocks, you will want to first declare the variable outside the blocks and assign them within. ActionScript Code:
The correct way to do this for AS3 is: ActionScript Code:
Notice that two different variables were used instead of 1 since they have different types. Also the variables were declared once outside of the if blocks instead of twice within. Alternatively, you could also use one variable with the * type. ActionScript Code:
|
mouseEnabled and Event Blocking
In ActionScript 1 and 2, instances with button events like onPress and onRollOver intercepts control of all button events that occurred over that instance. This means that if there was overlap between two instances with button events, the events occuring within the overlapping area would always go to the instance on top and never on the one below since those events were intercepted by the overlapping instance. Events to the underlying instance could be accessible in those overlapping areas only if all button events were removed from the topmost instance.
In ActionScript 3, the same concept applies, but the behavior is no longer dependant on button events like onPress since events are now handled exclusively with EventDispatcher. Instead, a property is used: mouseEnabled (flash.display.InteractiveObject.mouseEnabled). The mouseEnabled property actually kind of serves two purposes. First it prevents (true, default) or allows (false) mouse events going to instances below the topmost instance. It also enables (true, default) or disables (false) mouse instances from being dispatched to the that instance. It acts very much like the enabled property of AS1 and AS2. Notice the behavior of the following AS3 script. The topmost circle will be clicked when it is enabled. When not, events will go to the underlying circle. ActionScript Code:
Keep in mind that mouseEnabled is true by default. This means that even without button (or any) events associated with a display object instance, it will block events to those instances below it. If you don't want that to happen, you will have to appropriately set mouseEnabled = false where needed. |
Quote:
I'm just curious, what makes it faster? Any ideas about what implementation brings this improvement are welcome. |
Quote:
Its an internal method that doesn't rely on the get/set of the text property. Essentially any single method used to replace += will be much more efficient. |
mouseChildren with Event Propagation
The mouseChildren property (flash.display.DisplayObjectContainer.mouseChildren ) is a new property that allows you to essentially control the mouseEnabled of all the children of a sprite (or other display object container). This allows the parent sprite to have its own events without having to worry about interference with events coming from its children.
ActionScript Code:
Though ActionScript 3 now has a SimpleButton class (flash.display.SimpleButton). this property would play an important role in making custom buttons with the MovieClip or Sprite classes. Consider what would happen if you created a rollover event that caused a sprite or movie clip-based button to remove its current graphics and create new ones for a rollover state. With the children of that sprite capable of receiving mouse events, events would fire for the children within the button - events which would propagate to the main sprite. This could mean duplicate events as well as making the event target for those events the children of the button instead of the button itself. Setting mouseChildren to false you can prevent that from happening. The easiest demonstration is a simple click of a sprite containing another sprite. Change the value of mouseChildren between true and false and notice which sprite is designated as the target of the event: ActionScript Code:
When true (default), the sprite within the button that was clicked is marked as the target. When false, the button sprite itself is the target - something which is more desirable in this case. mouseChildren = true; output Code:
spriteButtonCode:
spriteGraphics |
rollOver and rollOut vs. mouseOver and mouseOut
The InteractiveObject class (flash.display.InteractiveObject) in ActionScript 3 has both rollOver and rollOut events as well as mouseOver and mouseOut events.
Both sets of events determine when a mouse enters or leaves the graphics area of an interactive object. The rollOver and mouseOver events fire when the mouse comes in contact with an interactive object, while rollOut and mouseOut occur when the mouse leaves the interactive object. Where they differ is with their interaction with interactive object children. The roll events (rollOver and rollOut) simplify the process and prevent interference with child events. Essentially, this is the same as using mouseOver and mouseOut with mouseEnabled set to false. mouseOver and mouseOut with mouseEnabled provide a parent sprite with events from its children. rollOver and rollOut keeps the events on the parent object. Example: toggle between the use of the ROLL_OVER & ROLL_OUT and MOUSE_OVER and MOUSE_OUT events. ActionScript Code:
You'll notice that with rollOver and rollOut, spriteButton is the target and doesn't receieve events from its children while the opposite is true for mouseOver and mouseOut. rollOver and rollOut output Code:
over: spriteButtonCode:
over: spriteGraphics1 |
DisplayObjectContainer contains()
With ActionScript 3, you can easily determine if a sprite or other display object container contains any otherr display object using the contains method (flash.display.DisplayObjectContainer.contains()). The contains method returns true if the display object passed is within the target display object container or any of its children. Example: ActionScript Code:
|