08-24-2006, 05:15 PM
|
#182
|

 |
San Francisco, CA (USA) |
|
 |
17,426 |
|
|
Quote:
|
Originally Posted by icio
I tried this 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
|
display objects only have access to the stage when they are within a visible display list (or, rather, a display list attached to the stage). To be able to have a valid reference to the stage from a sprite, you'd have to use addChild to add it to a container - either the stage itself or some other container attached to it.
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.
__________________

|
|
|
08-24-2006, 07:03 PM
|
#183
|
|
|
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
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!
|
|
|
08-24-2006, 07:42 PM
|
#184
|

 |
San Francisco, CA (USA) |
|
 |
17,426 |
|
|
Quote:
|
Originally Posted by Enemу
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
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!
|
gskinners post is your best approach (private variable usage prefered over helper class).
__________________

|
|
|
08-25-2006, 07:41 AM
|
#185
|
|
|
Quote:
|
Originally Posted by senocular
gskinners post is your best approach (private variable usage prefered over helper class).
|
You mean throwing an error if allowInstantiation == false ?
But what about compile time errors?
|
|
|
08-28-2006, 09:31 PM
|
#188
|

 |
San Francisco, CA (USA) |
|
 |
17,426 |
|
|
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:
Code:
// ActionScript 1 and 2
var i:Number = 1;
var i:String = 2;
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.
Code:
// ActionScript 3
var i:Number = 1;
var i:String = 2; // ERROR: duplicate definition or undefined property
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.
Code:
// ActionScript 3 INCORRECT
// (but works in AS1 and AS2)
if (my_btn.enabled == true) {
var returnValue:Number = 1;
}else{
var returnValue:Number = 0;
}
if (provideAsString == true) {
var returnValue:String = "1";
}else{
var returnValue:String = "0";
}
The correct way to do this for AS3 is:
Code:
// ActionScript 3 CORRECT
var returnValueNum:Number;
var returnValueStr:String;
if (my_btn.enabled == true) {
returnValueNum = 1;
}else{
returnValueNum = 0;
}
if (provideAsString == true) {
returnValueStr = "1";
}else{
returnValueStr = "0";
}
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.
Code:
// ActionScript 3 ALSO OK
var returnValue:*
if (my_btn.enabled == true) {
returnValue = 1;
}else{
returnValue = 0;
}
if (provideAsString == true) {
returnValue = "1";
}else{
returnValue = "0";
}
__________________

|
|
|
08-30-2006, 10:59 AM
|
#189
|

 |
San Francisco, CA (USA) |
|
 |
17,426 |
|
|
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.
Code:
function createCircle(name:String = ""):DisplayObject {
var circle:Sprite = new Sprite();
circle.name = name;
circle.graphics.lineStyle(0);
circle.graphics.beginFill(0xFF8080);
circle.graphics.drawCircle(50, 50, 50);
return circle;
}
circle1 = createCircle("circle 1");
circle2 = createCircle("circle 2");
circle2.x += 25;
addChild(circle1);
addChild(circle2);
circle1.addEventListener(MouseEvent.MOUSE_DOWN, click);
circle2.addEventListener(MouseEvent.MOUSE_DOWN, click);
function click(e) {
trace(e.target.name + " clicked."); // trace name
// disable and re-enable circle2 with each click
circle2.mouseEnabled = !circle2.mouseEnabled;
}
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.
__________________

|
|
|
08-30-2006, 02:01 PM
|
#190
|
|
|
Quote:
|
Originally Posted by senocular
since appendText is faster and more efficient.
|
I'm just curious, what makes it faster?
Any ideas about what implementation brings this improvement are welcome.
|
|
|
09-03-2006, 11:19 AM
|
#192
|

 |
San Francisco, CA (USA) |
|
 |
17,426 |
|
|
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.
Code:
spriteInstance.mouseChildren = false;
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:
Code:
// main button
var spriteButton:Sprite = new Sprite();
spriteButton.name = "spriteButton";
spriteButton.mouseChildren = true;
// graphics
var spriteGraphics:Sprite = new Sprite();
spriteGraphics.name = "spriteGraphics";
spriteGraphics.graphics.beginFill(0x4080A0);
spriteGraphics.graphics.drawCircle(50, 50, 25);
// add to display list
spriteButton.addChild(spriteGraphics);
addChild(spriteButton);
// events
spriteButton.addEventListener(MouseEvent.CLICK, click);
function click(evt:MouseEvent):void {
trace(evt.target.name);
}
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
mouseChildren = false; output
__________________

|
|
|
09-03-2006, 11:38 AM
|
#193
|

 |
San Francisco, CA (USA) |
|
 |
17,426 |
|
|
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.
Code:
// main button
var spriteButton:Sprite = new Sprite();
spriteButton.name = "spriteButton";
// graphics
var spriteGraphics1:Sprite = createGraphics("spriteGraphics1", 0xFF, 50, 50, 25);
var spriteGraphics2:Sprite = createGraphics("spriteGraphics2", 0x80, 50, 50, 15);
// add to display list
spriteButton.addChild(spriteGraphics1);
spriteButton.addChild(spriteGraphics2);
addChild(spriteButton);
// events
spriteButton.addEventListener(MouseEvent.ROLL_OVER, over);
spriteButton.addEventListener(MouseEvent.ROLL_OUT, out);
//~spriteButton.addEventListener(MouseEvent.MOUSE_OVER, over);
//~spriteButton.addEventListener(MouseEvent.MOUSE_OUT, out);
function over(evt:MouseEvent):void {
trace("over: " + evt.target.name);
}
function out(evt:MouseEvent):void {
trace("out: " + evt.target.name);
}
// create circles
function createGraphics(name:String, color:uint, x:Number, y:Number, radius:Number):Sprite {
var circle:Sprite = new Sprite();
circle.name = name;
circle.graphics.beginFill(color);
circle.graphics.drawCircle(x, y, radius);
return circle;
}
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: spriteButton
out: spriteButton
over: spriteButton
out: spriteButton
mouseOver and mouseOut output
Code:
over: spriteGraphics1
out: spriteGraphics1
over: spriteGraphics2
out: spriteGraphics2
over: spriteGraphics1
out: spriteGraphics1
__________________

|
|
|
09-03-2006, 12:14 PM
|
#195
|

 |
San Francisco, CA (USA) |
|
 |
17,426 |
|
|
Cleaning Up Event Listeners
When dealing with display objects in ActionScript 3, its important to remember that they can exist when not actually within a display list or visible on the screen. By removing objects from a display list, you do not stop events from occuring within that object (save for mouse events, obviously). This means that enterFrame events will continue to run for display objects even when removed from the screen. This is contrary to the behavior in ActionScript 1 and 2 where removal from the screen also meant removal from the entire movie, killing off all events related to it.
If you want to events like enterFrame to stop when you remove a display object from a display list, you'll want to do that manually, cleaning up after yourself when through with your display objects. To make this easier, you can use the removed event to determine when the display object has been removed from its parent. You can even use the added event to determin when its been added (thereby letting you reinstate an enterFrame listener, for example).
Example:
Code:
var sprite:Sprite = new Sprite();
sprite.addEventListener(Event.ADDED, addEnterFrame);
sprite.addEventListener(Event.REMOVED, removeEnterFrame);
// add/remove enter frame event
function addEnterFrame(evt:Event):void {
trace("added");
sprite.addEventListener(Event.ENTER_FRAME, enterFrame);
}
function removeEnterFrame(evt:Event):void {
trace("removed");
sprite.removeEventListener(Event.ENTER_FRAME, enterFrame);
}
function enterFrame(evt:Event):void {
trace("Time: " + getTimer());
}
// add and remove by clicking
stage.addEventListener(MouseEvent.CLICK, addRemove);
function addRemove(evt:Event):void {
if (this.contains(sprite)) {
this.removeChild(sprite);
}else{
this.addChild(sprite);
}
}
If removed wasnt used to cleanup the enterFrame event listener for the sprite when it was removed from the current display list, it would continue to run even though the sprite was removed from the screen.
output
Code:
added
Time: 813
Time: 927
removed
added
Time: 2509
Time: 2597
removed
__________________

|
|
|
|
Currently Active Users Viewing This Thread: 29 (1 members and 28 guests)
|
|
Uli
|
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -4. The time now is 10:25 AM.
|
|