[AS3] 動態複製顯示物件
如何不用連結(Linkage)的方式用AS3動態複製顯示物件。
執行結果:
有時候我們在元件庫中沒有或不想定義外部連結Class,或者要複製本來就是動態產生的物件,這時候可能就只好用動態複製的方式了。由於AS3沒有AS2的attachMovieClip以及duplicateMovieClip的方法,因此動態複製的功能就要自己來做了。
網路上有利用ByteArray來做memory copy,類似Array的深複製方法,不過這方法我沒成功。也有使用Loader再做一次載入的方法,要加一個Loader和監聽Complete事件,感覺上比較麻煩點。試過之後覺得以下兩種複製的方法比較好:其中一種是利用getQualifiedClassName取得該物件的Class名稱後,再利用getDefinitionByName將名稱轉為Class定義,也就是建構式。另一種寫法則是利用Object的constructor直接取得該物件的建構式。
先測試一下一個匿名,也就是動態產生的MovieClip經過getQualifiedClassName、getQualifiedSuperclassName、getDefinitionByName後的結果:
/** * Duplicate Display Object Example. * @Author: Scissor */ var tmpClip:MovieClip=newMovieClip(); trace(tmpClip); // [object MovieClip] trace(getQualifiedClassName(tmpClip)); // flash.display::MovieClip trace(getQualifiedSuperclassName(tmpClip)); // flash.display::Sprite trace(getDefinitionByName(getQualifiedClassName(tmpClip))); // [class MovieClip] trace(Object(tmpClip).constructor); // [class MovieClip]
實際使用時請注意,如果是在Flash IDE中的物件,一定要加上程式碼,若沒有的話可以在第一影格加上stop()或者play()即可。否則的話debug的時候雖然感覺上是複製成功,物件屬性都有複製到,可是在場景上卻完全找不到的現象(應該是Flash的Bug!如果您知道如何解決煩請留言跟大家說,感謝!):
import flash.events.MouseEvent; import flash.display.MovieClip; btnCopy1.addEventListener(MouseEvent.CLICK, onBtnCopy1Click); btnCopy2.addEventListener(MouseEvent.CLICK, onBtnCopy2Click); btnClear.addEventListener(MouseEvent.CLICK, onBtnClearClick); function onBtnCopy1Click(e:MouseEvent):void { var tmpClip:MovieClip = CopyDisplayObj(mcLogo) as MovieClip; tmpClip.x = Math.random() * stage.stageWidth; tmpClip.y = Math.random() * stage.stageHeight; tmpClip.name = "tmpClip"; addChildAt(tmpClip, 0); } function onBtnCopy2Click(e:MouseEvent):void { var tmpClip:MovieClip = DuplicateDisplayObj(mcLogo) as MovieClip; tmpClip.x = Math.random() * stage.stageWidth; tmpClip.y = Math.random() * stage.stageHeight; tmpClip.name = "tmpClip"; addChildAt(tmpClip, 0); } function onBtnClearClick(e:MouseEvent):void { for ( var i:int = this.numChildren - 1 ; i >= 0; --i ) { var tmpClip:DisplayObject = DisplayObject( this.getChildAt( i )); if ( tmpClip.name == "tmpClip" ) { this.removeChild( tmpClip ); tmpClip = null; } } } function CopyDisplayObj(target:DisplayObject, autoAdd:Boolean = false):DisplayObject { var targetClass:Class = getDefinitionByName(getQualifiedClassName(target)) as Class; var duplicate = new targetClass; if (autoAdd && target.parent) { target.parent.addChild(duplicate); } return duplicate; } function DuplicateDisplayObj(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; // add to target parent's display list // if autoAdd was provided as true if (autoAdd && target.parent) { target.parent.addChild(duplicate); } return duplicate; }
歡迎您留言與分享!(Welcome for comments or sharing!)
- [AS3] 限制中英文字數
- [Flash] SWF Compression (1) – 影像壓縮