Flashの学習(9) モーショングラフィックスで学ぶActionScript

第7章 ドラッグしてスナップー重ね合わせる

次はオブジェクトに吸着する方法だ。

キリンをドラッグして、もうひとつのキリンにドラッグすると、ぴったり吸着(スナップ)する。


https://sites.google.com/site/itouhiro/2009/20090523motion_as07_3.swf


ステージに2つのインスタンスを置いて、片方は色を変えておく。



スクリプト書くのは、シンボル qilin の1フレーム目だ。



それではコードを説明する。
getDepthというのはインスタンスの深度を得る。swapDepthsは深度を変更する。なぜ深度を変えるかというと、これを変えないと、ドラッグしたとき重ねる先のオブジェクトより下に来ることがあるんだ。これは見た目が自然じゃない。

見てのとおり、2つのオブジェクトの深度の差は3とか5だ。深度は大きいほうが上に来る。だから+100すれば、もうひとつのオブジェクトより上に来ることができるというわけ。
ちなみに深度をデバッグ出力してるのは、インスタンスに以下のムービークリップアクションを指定すればよい。

onClipEvent(load){
	trace(this._name +" の深度は "+this.getDepth());
}


いったん色の濃いキリンを動かすと、重ね順がやっぱりおかしくなるけど。


ありゃ、ほんとだ。次から気をつける。


コードのほうは…
startDragすると、マウスでオブジェクトをドラッグ開始する。
this.onPressでマウスを押したときにドラッグ開始して、this.onReleaseでマウスを離すとドラッグ終了。
this.onReleaseOutsideというのは、マウスをドラッグしたままFlash表示範囲の外に出て、そこでマウスを離した場合。


trace("eval(_droptarget)="+ eval(_droptarget)+":"+typeof eval(_droptarget));

これはデバッグ出力だが、以下のような文字列を吐く。

  eval(_droptarget)=:undefined
  eval(_droptarget)=_level0.penguin_mc:movieclip


ドラッグ先にムービークリップがないときは、_droptargetは空文字列(string)になる。eval(_droptarget)は stringではなく undefined になる。


ドラッグ先にムービークリップがあったときは、_droptarget/penguin_mc のような文字列(string)になる。これはslash syntaxといってFlash4との互換性のためこうなっている。eval(_droptarget)すると_level0.penguin_mcという見慣れたdot syntax(target path形式)になり、_xなどのプロパティにアクセスすることができるようになる。

_level0というのは_rootと同じ。ムービークリップが別のムービークリップを読み込むと その別のムービーの _root は _level1, _level2,.. となる。_level0 は元のムービークリップの_root。


evalJavaScriptと違って、文は解釈できない。変数名なら解釈できる。例:

var abc = 123;
trace(abc);              //123
trace("abc");            //abc
trace(eval("ab" + "c");  //123


ふむふむ


以下は、Objectを使って複数の値を返している。ObjectはC言語の構造体のように使える。

var obj = {newx:mc._x + 2, newy:mc._y + 2};
return obj;


次は吸着処理の応用編で、ピンボールの玉は特定の穴にしか はまらないのだ。


https://sites.google.com/site/itouhiro/2009/20090523motion_as07_7.swf


青玉はどこにも はまらないのか。
なんだか穴周辺の地面にピンボール持っていったとき、中途半端に表示が隠れるね。


ボールが半分地面に埋まっているのを表現しようと、地面オブジェクトを穴の下に用意したんだ。その地面オブジェクトが、穴に入っていないときも表示を隠すのでこうなってる。もう少し考えないとな。

ところでこのswfのスクリプトは、ball1, ball2, ball3, ball6のデザインが全部ちがうので、4つ別々のシンボルを用意して、各々にまったく同じスクリプトを書いて、実にまぬけなんだよなー。
_rootの1フレーム目にまとめて書けないかやってみたけど、onPressとonReleaseだと最後に登録したのオブジェクトが全部反応して動作がおかしい。ちょっとまだ理解不足だ。



第8章 データをまとめて処理する

また、ドラッグして吸着するサンプル。


https://sites.google.com/site/itouhiro/2009/20090523motion_as08_2.swf


この章は、本の説明の進め方がおかしい。

最初に、「MovieClipをさらにMovieClipでくるんで階層構造が深くなると MovieClip._droptargetではうまく座標を取得できない。そこでMovieClip.hitTestを使いましょう」とか言ってるけど、それでもうまく座標を取得できないのは同じなんだよ。

「補足および正誤表」 http://www.fumiononaka.com/Books/Errata.html 見ると

229ページ5行目文末に追加 「ドロップ先MovieClipとして、『Target_mc』と『Target2_mc』がメインのタイムラインに配置してあります。」

となってて、「MovieClipをさらにMovieClipでくるんで階層構造が深くなる」という問題がいつのまにかなくなってる……。


結局こうすれば「階層構造が深く」なったままで何とか動いたさ。
スクリプトの置き方は、このようになってる。



_rootの1フレーム目にこのスクリプトを置く。


シンボル qilin_targetは、こう。


それをさらに含むシンボル parent_target。


シンボル qilin。


ただ、動いてはいるけど、この直し方でいいのか分からないな。


前回のと、どこが違うの? 同じ動作に見えるけど。


MovieClip.hitTestを使うようになったおかげで、前回より吸着しやすくなった。

  • 前回は、オブジェクト2つがちょっと重なっただけでは吸着しなくて、「マウスカーソル」を重なり先のオブジェクト上に持っていくまで近づけてやっと吸着した。
  • 今回は、マウスカーソルが重なり先のオブジェクト上になくても、オブジェクトどうしが少しでも重なれば吸着する。実はオブジェクトを囲む四角が当たり判定になっているので、重なってなくても近くにくるだけで吸着する。


当たり判定か。STGファンとしては気になるところ。


APPENDIX A.共有オブジェクト―SharedObjectオブジェクト


SharedObjectを使うと、WebブラウザCookieのように、ユーザーのローカルディスクにデータを保存することができる。

動作サンプル。「TEXT」に入力した文字を「SUBMIT」ボタン押すと保存される。ほかのブラウザで見ても入力した文字が残ってるだろ?


https://sites.google.com/site/itouhiro/2009/20090523motion_as09_1.swf


どこに保存されるの? どこかネット上のサーバに保存される?


サーバには保存されないよ。動かしてるパソコンのハードディスクに保存される。
保存されたデータの消し方と実際に保存されてる場所は、以下にわかりやすい説明がある。
http://d.hatena.ne.jp/nitoyon/20090519/histroy_lso

APPENDIX B.SharedObjectオブジェクト・メソッドリファレンス


これでこの本終わり。


どうだったよ?この本


系統立てて書いてあるのと、説明が初心者向けといえないほど詳しいのが、他の言語を知ってるオレにはよかったよ。
ソースコード(flaファイル)がCD-ROMなりWeb配布されてないので完成形がわかりにくいね。

今後の課題としては、書いたスクリプトがいつ、何回実行されるかくわしく把握しておきたい。
ほかの言語は上から下に実行されるだけだけど、この本のActionScriptの書き方だとソースが分散してるからね。


Flashデザインラボ -プロに学ぶ、一生枯れない永久不滅テクニック (Design Lab+ 1-2)

Flashデザインラボ -プロに学ぶ、一生枯れない永久不滅テクニック (Design Lab+ 1-2)