以前のエントリー。
DisplayObject['constructor'] as Class
を使えば ActionScript 2 の DuplicateMovieclip みたいなことができるかもって記事です。
で、実際に DuplicateMovieclip みたいにするためにはプロパティを全コピー出来ないと duplicate にはなりません。
あの膨大なプロパティをどうやったらコピーできるかと悶々してたら Google 先生が教えてくれました。
kirupa.com にそのものズバリがありました。
http://www.kirupa.com/forum/showthread.php?p=1939827
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; } }
x, y… などのプロパティをコピーするのに DisplayObject.transform
をつかうのかぁ。
transform
でコピーできないプロパティは個別に設定するのか。
使い方は
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
ご存知、senocularさんの投稿です。
ためになるなぁ。
update 2011-01-17
muta244さんのコメントのByteArrayを使う方法はreadObjectをキャストすると戻り値がnullになり残念ながら使えないようです。
キャストしないと戻り値型はObjectになりプロパティ値にアクセスすることは可能です。
ただインスタンスそのものを再利用したいのでこの方法だと役不足でした。
import flash.utils.ByteArray; import flash.display.Sprite; var original:Sprite = new Sprite(); original.graphics.clear(); original.graphics.beginFill(0xffff00); original.graphics.drawRect(0, 0, 30, 30); original.graphics.endFill(); addChild(original); original.x = 100; var data:ByteArray = new ByteArray(); data.writeObject(original); data.position = 0; var copy:Object = data.readObject(); trace(copy.x); // 100 data.position = 0; var copy2:Sprite = data.readObject(); trace(copy2.x); // TypeError: Error #1034: 強制型変換に失敗しました。Object@3ce16d79 を flash.display.Sprite に変換できません。 data.position = 0; var copy3:Sprite = data.readObject() as Sprite; trace(copy3.x); // TypeError: Error #1009: null のオブジェクト参照のプロパティまたはメソッドにアクセスすることはできません。 |
タイムラインに配置したMCや生成したSpriteをByteArrayを使って再利用はどうも無理っぽい。
2011.01.16 12:53
先生、ご無沙汰してます!
こんな方法もあります。
var original:Sprite = new Sprite();
original.x = 100;
var data:ByteArray = new ByteArray();
data.writeObject(original);
data.position = 0;
var copy:Sprite = b.readObject() as Sprite;
trace(copy.x); // 100
ただ、どちらの方法にしろ、
private なプロパティはコピー出来ない気がするので(すいません、検証していないです)、
注意は必要そうですね。
2011.01.16 12:54
すいません、一カ所訂正です。
× var copy:Sprite = b.readObject() as Sprite;
○ var copy:Sprite = data.readObject() as Sprite;
2011.01.16 14:51
久しぶり、元気そうでなにより。
ByteArrayを使う方法は試したけど、readObjectの戻り値がnullになっちゃうんだけど。
ピンバック: Actionscript 3.0, AS2ライクにDuplicateMovieclipをするために2 – 完全に複製できない | イナヅマtvログ