Page 12 of 45 FirstFirst ... 2101112131422 ... LastLast
Results 166 to 180 of 669

Thread: ActionScript 3 Tip of the Day

  1. #166
    Quote Originally Posted by snick
    I was just wondering... if you were going to use a helper class anyway, why would you not just do this:
    ...
    I'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?
    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.

  2. #167

    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:
    <foo>
    	<foo />
    	<foo />
    	<foo />
    </foo>
    Code:
    // XMLList:
    <foo />
    <foo />
    <foo />
    Since you are dealing with one root node in the first example, it represents an XML object. In the second example, you have multiple nodes meaning you have an 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:
    Code:
    var myXML:XML = <foo>
    	<foo bar="bar1" />
    	<foo bar="bar2" />
    	<foo bar="bar3" />
    </foo>;
    
    trace(myXML.foo.@bar.toXMLString());
    /* Output:
    bar1
    bar2
    bar3
    */
    trace(myXML.foo.@bar is XMLList); // true
    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:
    Code:
    trace(myXML.foo[0].@bar is XMLList); // true
    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:
    Code:
    trace(myXML.foo[0].@bar[0] is XML); // true
    The same applies to XML
    Code:
    var myXML:XML = <foo>
    	<foo />
    </foo>;
    trace(myXML.foo is XMLList); // true
    The XML operations that can return more than one value (nodes, attributes, etc) will return XMLList instances.

  3. #168

    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).
    Code:
    package {
    	
    	import flash.display.Sprite;
    
    	public class MyClass extends Sprite {
    
    		public const MY_CONSTANT:String = "constant";
    
    		public function MyClass () {
    		}
    	}
    }
    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.

    Code:
    package {
    	
    	import flash.display.Sprite;
    
    	public class MyClass extends Sprite {
    
    		public const MY_CONSTANT:Array = new Array(1,2,3);
    
    		public function MyClass () {
    			MY_CONSTANT.push(4); // ok
    			MY_CONSTANT = new Array(5,6,7); // error
    		}
    	}
    }

  4. #169
    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

  5. #170
    Quote Originally Posted by Deviant1853
    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
    Actually, I might be wrong on that one. I should do some testing before commiting to that behavior (I might be thinking of something else).

    [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]

  6. #171
    Any time Senocular

  7. #172

    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:
    Code:
    package com.senocular.display {
    	
    	import flash.display.DisplayObject;
    	import flash.geom.Rectangle;
    	
    	/**
    	 * duplicateDisplayObject
    	 * creates a duplicate of the DisplayObject passed.
    	 * similar to duplicateMovieClip in AVM1
    	 * @param target the display object to duplicate
    	 * @param autoAdd if true, adds the duplicate to the display list
    	 * in which target was located
    	 * @return a duplicate instance of target
    	 */
    	public function duplicateDisplayObject(target:DisplayObject, autoAdd:Boolean = false):DisplayObject {
    		// create duplicate
    		var targetClass:Class = Object(target).constructor;
    		var duplicate:DisplayObject = new targetClass();
    		
    		// duplicate properties
    		duplicate.transform = target.transform;
    		duplicate.filters = target.filters;
    		duplicate.cacheAsBitmap = target.cacheAsBitmap;
    		duplicate.opaqueBackground = target.opaqueBackground;
    		if (target.scale9Grid) {
    			var rect:Rectangle = target.scale9Grid;
    			// WAS Flash 9 bug where returned scale9Grid is 20x larger than assigned
    			// rect.x /= 20, rect.y /= 20, rect.width /= 20, rect.height /= 20;
    			duplicate.scale9Grid = rect;
    		}
    		
    		// add to target parent's display list
    		// if autoAdd was provided as true
    		if (autoAdd && target.parent) {
    			target.parent.addChild(duplicate);
    		}
    		return duplicate;
    	}
    }
    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:
    Code:
    import com.senocular.display.duplicateDisplayObject;
    
    // create duplicate and assign to newInstance variable
    // using true for autoAdd automatically adds the newInstance
    // into the display list where myOldSprite is located
    var newInstance:Sprite = duplicateDisplayObject(myOldSprite, true);
    newInstance.x += 100; // shift to see duplicate
    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.

  8. #173
    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

  9. #174

    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.
    Code:
    package {
    	
    	import flash.utils.Proxy;
    	import flash.utils.flash_proxy;
    	
    	dynamic public class CustomObject extends Proxy {
    		
    		private var variables:Object = new Object(); // stores variables
    		
    		public function CustomObject() {
    		}
    		
    		// called when calling dynamic methods
    		override flash_proxy function callProperty(name:*, ... args):* {
    			
    			// convert name into string
    			name = String(name);
    			
    			var callType:String = name.slice(0,3); // get or set
    			var callVariable:String = name.slice(3); // variable name behind get or set
    			
    			switch(callType) {
    				
    				case 'get':
    					// if get, get from variables object if exists
    					if (callVariable in variables) {
    						return variables[callVariable];
    					}
    					return null;
    					
    				case 'set':
    					// if set assign to variables object
    					variables[callVariable] = args[0];
    			}
    		}
    	}
    }
    This example uses callProperty to accept generic get and set methods to get and set dynamic "variables" which are stored in the variables object.
    Code:
    // usage example
    var myObj:CustomObject = new CustomObject();
    trace(myObj.getMyVar()); // null
    myObj.setMyVar("foo");
    trace(myObj.getMyVar()); // foo
    myObj.setMyVar("bar");
    trace(myObj.getMyVar()); // bar
    trace(myObj.MyVar); // doesnt exist (get property error)
    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.

  10. #175
    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

  11. #176

    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:
    Code:
    package com.senocular.display {
    	
    	import flash.display.Graphics;
    	import flash.utils.flash_proxy;
    	import flash.utils.Proxy;
    	
    	/**
    	 * a graphics property substitute for DisplayObject instances
    	 * that can be duplicated
    	 */
    	public class GraphicsCopy extends Proxy {
    		
    		private var _graphics:Graphics;
    		private var history:Array = new Array();
    		
    		/**
    		 * graphics instance to recieve
    		 * drawing commands given to this GraphicsCopy instance
    		 */
    		public function get graphics():Graphics {
    			return _graphics;
    		}
    		public function set graphics(g:Graphics):void {
    			_graphics = g;
    			
    			// apply the graphics history to Graphics instance
    			copy(this);
    		}
    		
    		/**
    		 * constructor
    		 * @param graphics Optional Graphics instance to recieve
    		 * drawing commands given to this GraphicsCopy instance
    		 */
    		public function GraphicsCopy(graphics:Graphics = null) {
    			_graphics = graphics;
    		}
    		
    		/**
    		 * copies the graphics of a GraphicsCopy into this GraphicsCopy
    		 */
    		public function copy(graphicsCopy:GraphicsCopy):void {
    			var hist:Array = graphicsCopy.history;
    			history = hist.slice();
    			if (_graphics) {
    				var i:int;
    				var n:int = hist.length;
    				_graphics.clear();
    				for (i=0; i<n; i += 2) {
    					_graphics[hist[i]].apply(_graphics, hist[i + 1]);
    				}
    			}
    		}
    		
    		// PROXY overrides
    		override flash_proxy function callProperty(methodName:*, ... args):* {
    			methodName = String(methodName);
    			switch(methodName) {
    				case "clear":
    					history.length = 0;
    					break;
    				default:
    					history.push(methodName, args);
    			}
    			if (_graphics && methodName in _graphics) {
    				return _graphics[methodName].apply(_graphics, args);
    			}
    		}
    	}
    }
    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:
    Code:
    // MyClass.as Shape class using GraphicsCopy
    package {
    	
    	import flash.display.Shape;
    	import com.senocular.display.GraphicsCopy;
    	
    	class MyShape extends Shape {
    		
    		// graphicsCopy property
    		private var _graphicsCopy:GraphicsCopy;
    		public function get graphicsCopy():GraphicsCopy {
    			return _graphicsCopy;
    		}
    		
    		// constructor
    		function MyShape(){
    			_graphicsCopy = new GraphicsCopy(graphics);
    		}
    	}
    }
    Code:
    // in Flash
    // draw shape 1
    var shape1:MyShape = new MyShape();
    shape1.graphicsCopy.beginFill(0xFF80);
    shape1.graphicsCopy.lineStyle(2, 0);
    shape1.graphicsCopy.drawRect(0, 0, 50, 50);
    
    // draw shape2 using shape1's copied drawing
    var shape2:MyShape = new MyShape();
    shape2.graphicsCopy.copy(shape1.graphicsCopy);
    
    // add to display list
    addChild(shape1);
    addChild(shape2);
    shape2.x += 100;
    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.

  12. #177
    Quote Originally Posted by ignitrix
    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
    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

  13. #178
    Quote Originally Posted by senocular
    ...The Stage class (flash.display.Stage) is the class assigned to the stage object which is accessible from your main movie sprite/movie clip (or others within the same security sandbox) using the stage property...
    Is there anyway to give a static, non-DisplayObject class access to the stage? I tried many different workarounds, but could not figure out how to give it access to the stage without making it a non-static object...

  14. #179
    Quote Originally Posted by ignitrix
    Is there anyway to give a static, non-DisplayObject class access to the stage? I tried many different workarounds, but could not figure out how to give it access to the stage without making it a non-static object...
    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:
    /**
        My Stage
        version 1.0.0
        Created by Matthew Lloyd
        http://www.Matt-Lloyd.co.uk/
        
        This is release under a Creative Commons license. 
        More information can be found here:
        http://creativecommons.org/licenses/by-nc-sa/2.0/uk/
        
        ----------------------------------------------------------------

    */
    package com.deviant
    {
        
    import flash.display.*;

        public class 
    MyStage extends Sprite
        
    {
            public static var 
    instance:MyStage null;
            
            public function 
    MyStage()
            {}
            
            public static function 
    getInstance():MyStage
            
    {
                if(
    instance == null)
                    
    instance = new MyStage();
                return 
    instance;
            }
            
            public static function 
    getStage():Stage
            
    {
                return 
    getInstance().stage;
            }
            
            public static function 
    init(stg:Stage):void
            
    {
                
    stg.addChild(MyStage.getInstance());
                
    stg.scaleMode StageScaleMode.NO_SCALE;
                
    stg.align StageAlign.TOP_LEFT;
            }
        }

    The scale mode and the alignment arent nessicary they are just very useful for my needs.
    Last edited by Deviant1853; August 24th, 2006 at 04:32 PM.

  15. #180
    This worked excellent! Thanks Deviant

Page 12 of 45 FirstFirst ... 2101112131422 ... LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

Home About kirupa.com Meet the Moderators Advertise

 Link to Us

 Credits

Copyright 1999 - 2012