緑色になる謎


Flashを使ってて、ライブラリに入ってるムービークリップが、クラスを割り当てた時に緑色のアイコンになるときがあって、ずっと何故なんだろうと思ってたんですが、最近ようやく分かりました。

原因:割り当てたクラスがSpriteである

要するにMovieClipだと紫色で、Spriteだと緑色らしい。

うーん、FlashのIDE上でSpriteかMovieClipかを意識する必要はあんまり無い気がするんだけどどうなんだろう。まああるに越したことは無いのでいいっちゃいいんですが。CS3にはこの機能は無く、CS4からみたいです。ちなみにflash.display.Spriteでなくとも、これをextendsした独自クラスでもSpriteとして判定されて緑色に変化するみたいです。そんなところまで見てたのか、とちょっと感心しました。

swfの親の有無


たまに使おうとすると忘れてるのでメモ。

自分に親がいるかどうか確認する

this.loaderInfo.addEventlistener(Event.COMPLETE, selfLoadComp);
private function selfLoadComp(e:Event):void{
if(!loaderinfo.loader){
//親がいない
}
else{
//親がいる
}
}

これを最初に仕込んでおいて、initializeメソッドを呼ぶ前に何か処理させれば使えるはず。「自分が読み込まれたら」というイベントは自分だけで実行した時もEvent.COMPLETEするようです。

プリローダを実装している場合や、後読みのswfファイルである場合に、親となるswfがいないときでも正常に動作させるために、親がいない場合の特殊処理を書く時に使えると思ってます。特に親ファイルでデータをロードして子供に渡す場合、これを使うと親なしで子供だけでパブリッシュして実験できるようになったりするので便利かなーと。(間違えると2重に読み込んだりすることになりますがw)

この場では関係ないですが、Loaderで指定したURLがない場合、IOErrorEventになるわけですが、この時の失敗したURLをIOErrorEvent自体から取得する方法というのはないんでしょうか。どうにもロード失敗すると、loaderInfoのプロパティが一部しか取得できないみたいで、urlその取得できない値の一部の様子。

単品だったらそれでOKですが、何個もロードしている時はどれがエラーだったのかわかると便利そうなんですけどね。loaderにname属性をつけたらなんとかなるのかな・・・?

論理演算のXORを実現する


AS3ではビット単位でのXORはできるけど(^)、論理演算でのXORは用意されていないようなので、何とかできるように工夫してみた。

普通に

if(isA ^ isB){
//XORでtrueの処理
}

という感じで書くこともできるかと思ったら、数値型でないとパブリッシュできません。というわけで、

if(int(isA) ^ int(isB)){
//XORでtrueの処理
}

のような感じにしたらできました。一応traceさせると、

trace(Boolean(int(true) ^ int(true)));//false
trace(Boolean(int(true) ^ int(false)));//true
trace(Boolean(int(false) ^ int(true)));//true
trace(Boolean(int(false) ^ int(false)));//false

ということでXORが実現できました。まあビット単位の演算はできる以上当たり前ですし、遅くなったりしないのかという疑問も残りますが、条件文2つ書くよりはいいかなと。

計算もビット演算使った方が早い場合もあるようなので、ビット演算についてはもうちょっと使えるようにしたい。ビットシフトとか。

LoaderContext/ApplicationDomainの使い方を自分なりにメモ


未だによく分かってないのでメモ。

swfが親子になっていて、それらのクラスを共有させたい場合、これを使わないと、エラーが出て何が何だか分からなくなる。あと、音ファイルだけ別にしてgetDefinitionByNameする時とか。

基本は親と子で同じクラスを使いたいと思うので、親が子を読む際に自分と同じApplicationDomainに読み込む。

var context:LoaderContext = new LoaderContext();
context.applicationDomain = ApplicationDomain.currentDomain;
loader.load(path, context);

通常はApplicationDomain.currentDomainを使っていれば問題ないみたいなんですが、子供同士でバッティングしてしまうクラスがあると面倒なことになる様子。

この場合は

context.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);

として子供のcontextを逐次変更すれば、子供同士のクラスはバッティングしなくなりながらも、子供は親と共通のクラスを使える。はず。

何でもApplicationDomain.currentDomainにすればいいってもんでもないんですね。

loaderInfoからapplicationDomainを取る方法もあるみたいですが、勉強不足。

参考

そろそろTweensyを覚えたい。