[AS]MCにマスクをかけるときの順番。

いつも、どっちがどっちかわからなくなるのでメモ

まずAS3
ステージ上に、
インスタンス名:切り抜かれるMC(青い長方形)
インスタンス名:切り抜きの型となるMC(赤い三角)
二つのインスタンスを重ねた状態で、

切り抜かれるMC.mask = 切り抜きの型となるMC;

これで、青い三角ができあがる、と。

AS2だと

切り抜かれるMC.setMask(切り抜きの型となるMC);

切り抜かれるMCが常に最初と覚えておくことにしよう。

あとインスタンス名とかって全角の日本語でもOKなんですよねぇ。
AdobeMAXで城戸さんのセッションでやっててこういう使い方もありかと思いました。

[AS]SharedObjectについて

ユーザーのPCに変数情報等を保存できる。
Flash版のCokkieみたいなものらしい。
(そもそもCookieをよくわかっていないが)

何ができるかといったら、swfファイル間で同じ変数情報を共有可能。

使い方、owner.flaをつくりのそのフレームアクションに、

// 共有オブジェクトを作成する
var so:SharedObject =SharedObject.getLocal("MyData","/");
//containerBox0という箱を定義して値を設定
so.data.containerBox0="test0";
//ローカルにファイル(MyData.sol)を保存する。
var str = so.flush();

つづいて、user.flaを作ってそのフレームアクションに、

var so:SharedObject=null;
so=SharedObject.getLocal("MyData","/");
var tf:TextField = new TextField();
addChild(tf);
tf.text=String(so.data.containerBox0);

owner.flaをパブリッシュすると、MyData.solが保存される。
保存場所は上記スクリプトの場合は、
C:\Documents and Settings\(ユーザーID)\Application Data\Macromedia\Flash Player\#SharedObjects\NFWUQ76F\(ドメイン名)
もしくは
C:\Documents and Settings\(ユーザーID)\Application Data\Macromedia\Flash Player\(ドメイン名)
といった感じになるようだ。
参照サイト
ちなみにサーバーにあげないでローカルで試してるときは、(ドメイン名)はlocalhostになる。
ファイルができたことを確認して、user.flaをパブリッシュすると、text0が表示される。

ここで少し注意が必要でした。

owner→userの順でパブリッシュすると期待通りの動きですが、
user→owner→userの順でパブリッシュすると、MyData.solが削除されてしまいます。
理由はちゃんと理解してませんが。。。
多分先に作ったSharedObjectインスタンスに情報が入ってないから、なんちゃらかんちゃらな感じ。
なので情報が入ってるか入ってないかを判定して、入ってなかったら、その場でSharedObjectインスタンスを破棄するような処理が必要。

というわけでuser.flaを以下のように変更するとOKでした。

var so:SharedObject=null;
so=SharedObject.getLocal("MyData","/");
if (so.data.containerBox0==null) {
	so.clear();
	so=null;
} else {
	var tf:TextField = new TextField();
	addChild(tf);
	tf.text=String(so.data.containerBox0);
}

ファイル保存の際はエラー処理書いておかないとまずいですね。。。

[AS]removeChild()でガベージコレクション(GC)対象となる。

例えば、フレームアクションで、

var sp:Sprite = new Sprite();
this.addChild(sp);
removeChild(sp);
sp = null;

スプライトを作って、
メインのタイムラインに追加して、
メインのタイムラインから削除して、
スプライトの参照も削除

当然これで、spはGC対象となる。
でもこの場合ではsp=nullは特に要らないみたい。

var sp:Sprite = new Sprite();
this.addChild(sp);
removeChild(sp);

この場合は、これでもspはGCの対象となるようす。
removeChild()した時点で、GC対象となっている。

removeChildについてのドキュメントより、

DisplayObjectContainer インスタンスの子リストから指定の child DisplayObject インスタンスを削除します。
削除された子の parent プロパティは null に設定されます。その子に対する参照が存在しない場合、そのオブジェクトはガベージコレクションによって収集されます。

参考サイト:
FlashPlayer9のガベージコレクタのメモリ解放の考察

DisplayObjectじゃない(addChildしてない)変数をGC対象とするときは○○=nullを使って参照を切ればいいってことなのかな。

[AS]progressionでpreloaderのインスタンスにアクセスする方法

教えてもらったこと。
index.asにて

MovieClip(stage.getChildAt(0))

でpreloader本体を指定可能。

例)
preloader.flaに、hoge1_mcとかhoge2_mcとか置いてあった場合。
index.asからhoge1_mcにアクセスするには、

MovieClip(stage.getChildAt(0)).hoge1_mc

でOK

[FD]FlashDevelopでFlex SDKのコンパイルの際のドキュメントクラス的なものについて

緑色の↓(下矢印)のついたアイコンのファイルがコンパイル対象となる。
※右クリックでAlwaysCompileにチェックが入ってる
mxmlとかasファイルとかに指定する。

変更するときは、変更したいファイルを右クリックしてAlwaysCompileにチェック。
(さっきまでチェックされてたファイルのアイコンから緑下矢印が消える)

[AS]ドキュメントクラスでのthisについて

ドキュメントクラスは、MovieClipかSpriteを継承していないといけない。
そのためどっちを継承したかでthisの性質が変わってくる模様。

以下、Spriteを継承しててはまったこと。
ステージにインスタンス名myMcのムービークリップを配置。
ドキュメントクラスをMain.as

//Main.as
public class Main extends Sprite {
public function Main() {
var main2:Main2 = new Main2(this);
}
}
//Main2.asのコンストラクタ
public function Main2(container) {
var container2:Sprite = container

trace(container2.myMc.x);
}

これだと、container2にmyMcなんてプロパティ無いよと起こられる。
おそらくSpriteはDynamicじゃないからってことかな?
でも、↓こう書けばSprite継承でも参照できるみたい。
trace(container2[“myMc”].x);
まぁcontainer2:Spriteとせずに、Mainとすれば問題ないけど。

最初からMainはMovieClipを継承してれば何の問題もない

//Main.as
public class Main extends MovieClip{
public function Main() {
var main2:Main2 = new Main2(this);
}
}
//Main2.asのコンストラクタ
public function Main2(container) {
var container2:MovieClip= container
trace(container2.myMc.x);
}

結論としては、ドキュメントクラスはMovieClipを継承しといた方が無難・・・

[FD]FlashDevelopで変数をgetter/setterにするときの注意

通常、変数にカーソル当ててctrl+shift+1をすると、getterとかsetter作れるショートカット。
このとき変数名に_(アンダーバー)は混ぜない方がいいみたい。

例えば、
var hoge_Hogege:String;
これをショートカットでgetter作ろうとすると、

public function get Hogege(): { return hoge_Hoge; }

このように、予期しない形になります。

ちなみに↓これは
var hoge_Ho:String;

public function get hoge(): { return hoge_Ho; }

こんな感じ。

なので最初からアンダーバーを含まないようにすれば
var hogeHoge:String;

public function get hogeHoge():String { return _hogeHoge; }

こんな感じ。
(そしていつもどおり元の変数にアンダーバーが付与)
(var _hogeHoge:String;)

[AS]クラスインスタンスを作って表示リストに追加を1行で書く

たとえば、ライブラリにMCがあり、それはクラス名Mcでリンケージしてある。

一般的には

var mc:Mc = new Mc();//インスタンス作成
addChild(mc)//表示リストに追加

一行で書くと

var mc:Mc = Mc(addChild(new Mc()));

もしくは

var mc:Mc = addChild(new Mc()) as Mc;

※addChildの返り値はDisplayObjectなので、型変換が必要

2009/03/04追記
※DisplayObjectで問題なければしなくても良い

[AS]functionの中のfunctionのthisについての注意

関数の中に関数を入れた場合(関数クロージャというらしい)、中の関数でのthisの扱いには注意が必要。

例えば。。。

//フレームアクション
function main(){
trace(this);
//mc赤い四角定義
	var mc = new MovieClip();
	mc.graphics.beginFill(0xFF0000);
	mc.graphics.drawRect(0,0,100,100);
	mc.graphics.endFill();
	sub();
//関数クロージャ(たぶん)
	function sub(){
trace(this);
		addChild(mc);
	}
}
main();

上記を実行すると100×100の赤い四角がx:0,y:0の位置に表示される。
ここで注意したいのが、function subの中のaddChild(mc);
これは本来の文法的にはDisplayObjectContainer.addChild(mc)
DisplayObjectContainerが記載されてないから、thisになるのか、
と思うとそうでもない。。。

this.addChild(mc)

これはエラーになります。
finction sub()のthisと、function main()のthisはtrace結果を見ると違うものです。
よって、関数クロージャのaddChild(~)は、thisが省略されてるわけではないってことで。
※この例では”メインのタイムライン”になっているみたい。(フレームアクションなので)

[AS][?]progression addCommandのexecute()について

_onload(),_onInit(),_onCastAdded(),_onCastRemoved(),_onGoto()などのoverride系のメソッドの中のaddCommand()は、execute()無しで、自動的に実行されるみたい。

addCommand()はリスト(CommandList?)にコマンドを追加するメソッドで、色んなクラスに入っている。
が、しかし、
CommandListクラスのメソッドのaddCommand()と
SceneObjectクラスのメソッドのaddCommand()とでは
動作の意味が若干違うみたい。(ドキュメントに書いてあることが違うし)