Copying a MovieClip in AS3

Copying a Movie Clip in ActionScript 3. Can’t be done. Right? Wrong.

Well, duplicateMovieClip is certainly gone, but there are still ways of making copies – running an objects constructor for example.

The basic way of doing this (which you no doubt know) is running the constructor of an object directly:

1
2
3
4
5
private var _circle = new customCircleClass
 
// "copy"
 
private var _circle2 = new customCircleClass

This, however, requires you to know the name of the constructor you are running. In many cases you might not. Lets look at this likely scenario:

You are using the TileList component as a menu for a drag-and-drop application.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package examples{
 
 import flash.display.MovieClip;
 import fl.controls.TileList;
 import fl.data.DataProvider;
 import fl.events.ListEvent;
 
public class dragDropper extends MovieClip{
 
	private var _tileList: 		TileList;
 
	private var _dataProvider: 	DataProvider;
 
	public function dragDropper(){
 
 		// to be added
 
 	}
 }
 
}

Next, lets make some objects to put in our lists. This is customCircle.as :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package examples{
 
import flash.display.Sprite;
 
public class customCircle extends Sprite{
 
public function customCircle(){
 		graphics.beginFill(0x440000,1);
 		graphics.drawCircle(10,10,10);
 		graphics.endFill();
 	}
}
 
}

I’m sure you can guess the rest. Let’s continue with the constructor:

13
public function dragDropper(){
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// Create some different shapes to add to TileList
 
 var circle = new customCircle();
 
 var square = new customSquare();
 
 var triangle = new customTriangle();
 
// Set up Data Provider
 
 _dataProvider = new DataProvider();
 
 _dataProvider.addItem( {source:circle} );
 
 _dataProvider.addItem( {source:square} );
 
 _dataProvider.addItem( {source:triangle} );
 
// Create TileList and set Data Provider
 
 _tileList = new TileList();
 
 _tileList.width = 160;
 
 _tileList.height = 60;
 
 _tileList.setStyle("contentPadding", 5);
 
 _tileList.setRendererStyle("imagePadding", 5);
 
_tileList.dataProvider = _dataProvider;
 
addChild( _tileList );
 
}

Which gives us this:



Which is great. But we need it to do more than just look cool, so we add a listener:

13
_tileList.addEventListener(fl.events.ListEvent.ITEM_CLICK, listItemClick);

Now we can get to the point of all this, that is how to copy Display Objects in AS3. Tile Lists dispatches List Events when they are clicked; they are different from ordinary Events in that they carry a reference to the object that has been clicked. Many people write custom Event classes for this exact purpose, but that is another chapter.

We can now access and manipulate the clicked object:

40
41
42
43
public function listItemClick(e:ListEvent){
	addChild( e.item.source);
	e.item.source.startDrag();
}

This will make the object draggable but also removes the object from the Tile List, as it can not be a child to both the stage and the Tile List.

So were do we go from here? We can’t know which tile the user will click ahead of time. Luckily all Objects have the constructor property, which holds a reference to their Constructor:

40
41
42
43
44
public function listItemClick(e:ListEvent){
	var newCursor = new e.item.source.constructor
	addChild( newCursor );
	newCursor.startDrag();
}

Good times. But this only creates a blank instance Object you are copying. For copying objects with states preserved check back next week!
You can read the follow up here!