MTASCと戯れる その1 コンストラクタまわり

まずは、習作5(http://nabetani.sakura.ne.jp/flash/etude20050606.html)を読んでみよう。この習作はマウスを押すごとに、カラフルな"+"の形の星が四方にはじけて、しばらくすると消えるFlashだ。出現する星の数や色を変更してみるのを第一の目標に、ざーっと全体を眺めてコンストラクタを調べる。
ざっと見たかんじクラス定義はJavaぽい。いまどきのクラスベースOOPによくあるかんじ。クラスと同名の関数がおそらくコンストラクタだし、static mainがエントリポイントだろう。というわけで、mainを読む。短い。こんなん。

  static function main()
  {
    var t = new Etude5(_root);
  }

Etude5自体のオブジェクトを生成してるだけ。_rootってのは組込み変数でFlashのキモであるムービークリップのうち、一番土台となる部分。それを引数に自分自身のコンストラクタを呼ぶことで、オブジェクトを生成する、と。
ところで、生成したオブジェクトはvar tにつっこまれてるけど、これは必ず確保しないといけないのだろうか? 後でtを使うわけでもないので、コードとしては不必要にみえる。試しにvar tを抜いてみた。しっかりparse errorになってしまった。かなしい。ま、このへんはイディオムか。
次はコンストラクタ周辺を見よう。

  var mc;
  var mDepth;
  var mL;

  function Etude5( mc0 )
  {
    mc = mc0;
    mc.man = this;
    init();
  }

  function init()
  {
    mDepth = 0;
    mc.clear();
    mc.onEnterFrame = function(){  this.man.ef(); }
    mc.onMouseDown =  function(){  this.man.md();  }
    mL = new Array;
  }

まだなんだかよくわからないが、インスタンス変数が三つ定義されている。コンストラクタの中では、引数mc0をインスタンス変数に格納して、初期化関数initを呼ぶだけ。mc0の中身はルートムービークリップ
コンストラクタで注意すべきなのは、mc.manに自分自身(this)が格納されていること。mcというのはムービークリップなので、そのプロパティmanに自分自身をいれておく。こうすると、ムービークリップとこのオブジェクト自体が相互参照して便利なんだろう、多分。ところで、このmanはあらかじめムービークリップに備わった機能なのか、それとも勝手にプロパティを追加しているだけなのか後で調べないといけない。多分勝手に追加してるだけだと思うけど。
で、次はinit。インスタンス変数mDepthを0で、mLを配列で初期化。ムービークリップをclear()して、ハンドラを二つくっつけている。で、ハンドラはクロージャーだな。ハンドラの中のthisは(おそらく)ムービークリップを指すので、this.manとすることでEtude5オブジェクトを取得して、その中の関数を読んでいる。ここで相互参照が役立ってる。

で、疑問ふたつ。

  1. インスタンス変数の初期化は宣言時にできないか?
  2. ハンドラはクロージャなはずなので、this.manなんてまわりくどいことをせずになんとかならんか?

結論からいうと両方OKなようだ。こう書きかえてもちゃんと動いた。

  var mc;
  var mDepth = 0;
  var mL = new Array();

  function Etude5( mc0 )
  {
    mc = mc0;
    init();
  }

  function init() {
    mc.clear();
    var self = this;
    mc.onEnterFrame = function(){  self.ef(); }
    mc.onMouseDown =  function(){  self.md(); }
  }

で、ここで関数呼びだしの関係が終了してしまう。クリックを感知してハンドラmd()が動くまでは何もしないわけですね。とりあえず、ここで一区切り。次はハンドラだ。