346
|
Chapter 10, ActionScript
#77 Clone an Object
HACK
Only enumerable properties are attached to the cloned object. Enumera-
ble properties include those you would usually want to search through
within a for...in loop (such as custom properties and methods created by
the developer) but not preset properties that define how the class works
internally or ActionScript methods.
We use the undocumented ASSetPropFlags( )
[Hack #82] to protect our
new Object.clone( ) method from deletion and hide it from for...in loops.
You can test the clone( ) method as follows:
// Create an object containing a nested object for testing
obj = {name:"test", num:10, bool:true,
childObj:{childName:"original child name", childNum:5}, root:_root};
// Clone the object
cloneOfObj = obj.clone( );
// Change a value in the new object
cloneOfObj.childObj.childName = "changed child name";
// Check to see if the two values are independent (they are)
trace("obj.childObj.childName = " + obj.childObj.childName);
trace("cloneOfObj.childObj.childName = " + cloneOfObj.childObj.childName);
The preceding code demonstrates how both the clone object and its child
object are independent of the original object or its child object. The clone( )
method saves you from having to copy properties and user-defined methods
manually if you want a new copy of an object.
Cloning for Motion Graphics
Call me old-fashioned, but I prefer to look at data and its effects visually, so
here’s another example in which you can see the difference between data
that has been cloned versus data copied by reference.
The following code creates an
sData (“sprite data”) object, which is used to
control several semi-transparent circular clips to produce a particle effect.
The effect works by creating many identical movie clips, each of which has
an independent instance of
sData on its timeline.
function animate( ):Void {
this.sData = sData.clone( )
this._x = this.sData.x;
this._y = this.sData.y;
this.lineStyle(10, 0x404040, 10);
this.moveTo(-0.5, 0);
this.lineTo(0, 0);
this.onEnterFrame = function( ) {
this.sData.x += Math.random( ) * this.sData.s - sData.s / 2;
this.sData.y += Math.random( ) * this.sData.s - sData.s / 2;
this._x = this.sData.x;
this._y = this.sData.y;
Clone an Object #77
Chapter 10, ActionScript
|
347
HACK
};
}
var sData:Object = new Object( );
sData.x = 275;
sData.y = 200;
sData.s = 4;
for (var i:Number = 0; i < 500; i++) {
var dot:MovieClip = this.createEmptyMovieClip("dot" + i,
this.getNextHighestDepth( ));
dot.onEnterFrame = animate;
}
Notice that the preceding code contains an example of a common and
proper use of copying a movie clip by reference. The
dot variable holds a ref-
erence to the movie clip instance
doti. It always points to the movie clip cre-
ated within the loop without making a clone of the clip.
Each clip is unique and maintains its independent properties, such as size
and position. The code creates a simple Brownian motion (random particle
movement) simulation, as seen in gases and in Figure 10-7. All 500 clips are
independent.
If you change the first line in the animate( ) function so that it copies by ref-
erence instead of cloning:
this.sData = sData;
you get a totally different result, as shown in Figure 10-8.
Figure 10-7. Brownian motion simulated with 500 movie clips
Figure 10-8. Failing to clone (separate) the sData results in a clumpy animation

Get Flash Hacks now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.