Flashの学習(10) オブジェクト指向で考えるActionScript

オブジェクト指向で考えるActionScript―Flash MXでより進んだWebデザイン作成」もまたまた野中氏の本だ。


オブジェクト指向で考えるActionScript―Flash MXでより進んだWebデザイン作成

オブジェクト指向で考えるActionScript―Flash MXでより進んだWebデザイン作成

  • 作者: 野中文雄
  • 出版社/メーカー: セレンディップ
  • 発売日: 2003-07
  • メディア: 単行本

  • おすすめ度の平均:
    もっと高く評価されるべき


前回まで学習していた「モーショングラフィックスで学ぶActionScript」の続編のような本だな。この本の中で「『モーショングラフィックス…』のp220〜をご参照ください」とよく書いてある。


目次

第1章 ActionScriptの基礎
第2章 function(関数)を使う
第3章 イベントハンドラメソッドを使ったスクリプティング
第4章 オブジェクトを使ったスクリプティング
第5章 イベントを捉える―リスナー
第6章 オブジェクトを拡張する

第1章 ActionScriptの基礎

MovieClipアクション(FrameではなくMovieClip Instanceに書くスクリプト)に書けるEventHandlerは以下がある。

  • onClipEvent(@@).. @@はmovieEvent
    • load ムービークリップインスタンス化され、タイムラインに表示されると、アクションが即座に開始されます。
    • unload ムービークリップがタイムラインから削除された後、最初のフレームでアクションが開始されます。Unload ムービークリップイベントに関連するアクションは、該当するフレームにアクションが割り当てられる前に処理されます。
    • enterFrame アクションはムービーのフレームレートで継続的にトリガされます。enterFrame クリップイベントに関連するアクションは、該当するフレームに割り当てられているフレームアクションの前に処理されます。
    • mouseMove マウスを動かすたびに、アクションが開始されます。現在のマウス位置を指定するには、_xmouse と _ymouse プロパティを使用します。
    • mouseDown 左マウスボタンを押すと、アクションが開始されます。
    • mouseUp 左マウスボタンを離すと、アクションが開始されます。
    • keyDown キーを押すと、アクションが開始されます。最後に押したキーに関する情報を調べるには、Key.getCode メソッドを使用します。
    • keyUp キーを離すと、アクションが開始されます。最後に押したキーに関する情報を調べるには、Key.getCode メソッドを使用します。
    • data データが loadVariables または loadMovie アクションで受信されると、アクションが開始されます。loadVariables アクションで指定すると、最後の変数がロードされたときに data イベントが 1 回だけ発生します。loadMovie アクションで指定すると、各データセクションが読み込まれるたびに、data イベントが繰り返し発生します。
  • on(@@@).. @@@はmouseEvent
    • press ポインタがボタン上にある間に、マウスボタンを押します。
    • release ポインタがボタン上にある間に、マウスボタンを離します。
    • releaseOutside ポインタがボタンの内側にあるときにマウスボタンを押した後で、ポインタがボタンの外側にあるときにマウスボタンを離します。
    • rollOut ポインタがボタン領域の外側に移動します。
    • rollOver マウスポインタがボタン上を移動します。
    • dragOut ポインタがボタン上にある時に、マウスボタンを押し、そのままボタン領域の外側に移動します。
    • dragOver ポインタがボタン上にある時にマウスボタンを押し、そのままボタンの外側に移動し、またボタン上に戻ります。
    • keyPress ("key") 指定されたキーを押します。パラメータの key 部分を指定するには、『Flash ユーザーガイド』の付録 B、「キーボードのキーとキーコードの値」 に示されているキーコードを使用するか、Key オブジェクトのプロパティ一覧 に示されているキー定数を使用します。


こうして一覧して比較すると違いがわかってくる。
on()のほうはマウス動作監視とキーの入力に対応している。
onClipEvent()はそれ以外にもある。
けど、マウスクリックに反応するのは2つのEventHandlerのどっちにもあるね。重複している?


本によると、on(press)..はそのスクリプト書いたMovieClipをクリックしたときだけ反応するが、onClipEvent(mouseDown)..はステージ上のどこをクリックしても反応してしまう、という違いがある。


試しに作ってみた。
キリンをクリックするとステージまるごと右や左に移動する。


https://sites.google.com/site/itouhiro/2009/20090524oop_as01_1.swf


確かに、onClipEvent(mouseDown)..はキリン以外をクリックしても反応するなあ。

スクリプトはこんな感じ。


気がついたのは、on(press)..ってマウスボタンをプレスしているあいだはずっとイベント発行しそうに思ったけど、クリックした瞬間一度だけしかイベント発行しない。 trace文入れて調べた。 onClipEvent(mouseDown)..も同じくクリックした最初の一瞬だけイベント発行する。


ところでこの本では、変数の命名ハンガリアン記法を使って長い変数名になってる。この筆者の趣味かな……と思ってたけど、Flash開発元のオススメだったんだな。
Flashでの命名http://www.adobe.com/jp/support/kb/ts/228/ts_228649_ja-jp.html

個人的には短い変数名のほうが認識しやすくてよいと思ってるので、マネしないけど。

第2章 function(関数)を使う

  • 個々のオブジェクトが直接他のオブジェクトを操作するのはよくない。
  • 個々のオブジェクトは他のオブジェクトにリモコン信号を送るだけにして、リモコン信号を受け取ったそのオブジェクト自身が主体的に動くように設計するべし。
  • 「リモコン信号を送る」というのはActionScriptでは「functionを呼び出す」に当たる。

と書いてある。


ひきこもり学生の自立支援みたいだな……


動作共有化のための関数と、他のオブジェクトが呼び出す用の関数は、分けたほうがよいとも書いてある。


ところで、
関数に与える引数は参照渡しなのか、値渡しなのか、よく分からないので実験。

_rootの1フレーム目にこう書いて、Ctrl+Enter[ムービーのプレビュー]すると

function func_change_num(num){
	num += 10;
}
function func_change_array(array){
	array[0] += 20;
}
function func_change_bool(bool){
	! bool;
}
function func_change_str(str){
	str += "def";
}
function func_change_obj(obj){
	obj.a += 30;
	obj.c += "def";
}


var n = 5;
trace("n="+n);
func_change_num(n);
trace("n="+n);


var ar = [1,2,3];
trace("ar[2]="+ar[2]);
func_change_num(ar[2]);
trace("ar[2]="+ar[2]);

trace("ar[0]="+ar[0]);
func_change_array(ar);
trace("ar[0]="+ar[0]);


var bl = true;
trace("bool="+bl);
func_change_bool(bl);
trace("bool="+bl);

var str = "abc";
trace("string="+str);
func_change_str(bl);
trace("string="+str);


var obj={a:11, b:22, c:"hello"};
trace("obj.a="+obj.a+", obj.c="+obj.c);
func_change_obj(obj);
trace("obj.a="+obj.a+", obj.c="+obj.c);

trace("string="+obj.c);
func_change_str(obj.c);
trace("string="+obj.c);


以下の結果が得られた。

n=5
n=5
ar[2]=3
ar[2]=3
ar[0]=1
ar[0]=21
bool=true
bool=true
string=abc
string=abc
obj.a=11, obj.c=hello
obj.a=41, obj.c=hellodef
string=hellodef
string=hellodef

わかったこと。

以下は 値渡し。(呼び出し先に渡した中身を触っても、呼び出し元には影響しない)

  • 数値
  • bool
  • 文字列
  • 配列の一要素(数値、文字列)


以下は 参照渡し。(呼び出し先に渡した変数の中身を触ると、呼び出し元の変数まで書き換える)

  • 配列まるごと(中身は数値、文字列)
  • Object型


こんな実験は必要なのかい?


手足のように扱うため、細かい挙動を知っておく必要があるんだ。何年も使っていればいやでも覚えてくるものだが、ActionScript1.0なんて今後使われなくなっていくだろうからな。早めに覚えておく。


次に、varで宣言した変数は関数をぬけると消えるといっていたので、returnで返したときになくなっていることがないか調べた。C言語ではポインタ渡し(=参照渡し)でこれが起きたような…。

function func_num(){
	var num = 10;
	return num;
}
function func_ary(){
	var ary = [101,102,103];
	return ary;
}
function func_ary_elem(){
	var ary = [101,102,103];
	return ary[0];
}
function func_obj(){
	var obj = {number:1, string:"hello"};
	return obj;
}
function func_obj_elem_n(){
	var obj = {number:1, string:"hello"};
	return obj.number;
}
function func_obj_elem_s(){
	var obj = {number:1, string:"hello"};
	return obj.string;
}

the_number = func_num();
trace("the_number="+the_number+"("+typeof the_number+")");

the_array = func_ary();
trace("the_array="+the_array+"("+typeof the_array+")");
trace("the_array[0]="+the_array[0]+"("+typeof the_array[0]+")");

array_element = func_ary_elem();
trace("array_element="+array_element+"("+typeof array_element+")");

the_object = func_obj();
trace("the_object="+the_object+"("+typeof the_object+")");
trace("the_object.number="+the_object.number+"("+typeof the_object.number+")");
trace("the_object.string="+the_object.string+"("+typeof the_object.string+")");

object_element_n = func_obj_elem_n();
trace("object_element_n="+object_element_n+"("+typeof object_element_n+")");

object_element_s = func_obj_elem_s();
trace("object_element_s="+object_element_s+"("+typeof object_element_s+")");
the_number=10(number)
the_array=101,102,103(object)
the_array[0]=101(number)
array_element=101(number)
the_object=[object Object](object)
the_object.number=1(number)
the_object.string=hello(string)
object_element_n=1(number)
object_element_s=hello(string)

うーむ、すべて関数を終えても残っているではないか。
←ローカル変数保持はActivationオブジェクトが行い、GarbageCollectionによって使われていなければ削除を行うとのこと。


if(@@)の@@の部分に来る条件が falseになるのは、式または変数が以下の値を返すとき

  • false
  • undefined
  • null
  • NaN (Not a Nunmber:数字にできない数字)
  • 数字の 0
  • 空文字列 ""
  • 数字に変換したとき0になる文字列 "abc"など (←これはJavaScriptと動作が異なる)

これ以外はtrueを返す。

実験してみた。

trace("false:" +Boolean(false) + ":"+typeof false);

//aを未定義のまま使用
trace("a:" +Boolean(a) + ":"+typeof a);
b = null;
trace("b:" +Boolean(b) + ":"+typeof b);

trace("1:" +Boolean(1) + ":"+typeof 1);
trace("0:" +Boolean(0) + ":"+typeof 0);

trace("123/0="+123/0);
trace("123/0:" +Boolean(123/0) + ":"+typeof 123/0);
trace("0/456="+0/456);
trace("0/456:" +Boolean(0/456) + ":"+typeof 0/456);

trace("'':"    +Boolean('')    + ":"+typeof '');
trace("'abc':" +Boolean('abc') + ":"+typeof 'abc');
trace("'abc789':" +Boolean('abc789') + ":"+typeof 'abc789');
trace("'789':" +Boolean('789') + ":"+typeof '789');

the_array = [1,2];
trace("the_array:"    +Boolean(the_array)    + ":"+typeof the_array);
empty_array = [];
trace("empty_array:"    +Boolean(empty_array)    + ":"+typeof empty_array);
false:false:boolean
a:false:undefined
b:false:null
1:true:number
0:false:number
123/0=Infinity
123/0:true:NaN
0/456=0
0/456:false:NaN
'':false:string
'abc':false:string
'abc789':false:string
'789':true:string
the_array:true:object
empty_array:true:object

NaNなのにtrueになってるケースがあるぞー。 なぜだろう? 0で除算してる時点で問題だが。


第3章 イベントハンドラメソッドを使ったスクリプティング

Event Handler Method を使うと、MovieClipアクションに書かなくても、Frameアクションにスクリプトを書けるようになる。
(ちなみにActionScript3.0ではMovieClipアクションがなくなって、Frameアクションは残っている)


キリンをクリックするswfだ。今度はキリンの外はクリックしても意味ないぞ。


https://sites.google.com/site/itouhiro/2009/20090524oop_as03_1.swf


今回のスクリプトはこうなってる。左側のキリン qilin2_mc にはMovieClipアクションがなくて、かわりに _rootの1フレーム目に書かれたフレームアクションだけで動作している、というのが特徴だ。


MovieClipオブジェクトのイベントハンドラの一覧はこうなってる。

  • MovieClip.onData すべてのデータをムービークリップ内にロードすると、呼び出されます。
  • MovieClip.onDragOut ポインタがボタン外にあるときに、ボタン上でマウスボタンを押し、そのままボタン領域外に移動すると、呼び出されます。
  • MovieClip.onDragOver ポインタがボタン上にあるときに、マウスボタンを押し、そのままボタン外に移動し、またボタン上に戻ると、呼び出されます。
  • MovieClip.onEnterFrame ムービーのフレームレートで継続的に呼び出されます。enterFrame クリップイベントに関連するアクションは、該当するフレームに割り当てられているフレームアクションの前に処理されます。
  • MovieClip.onKeyDown キーを押すと呼び出されます。最後に押したキーに関する情報を調べるには、Key.getCode メソッドおよび Key.getAscii メソッドを使用します。
  • MovieClip.onKeyUp キーを離すと、呼び出されます。
  • MovieClip.onKillFocus ボタンからフォーカスを移動すると、呼び出されます。
  • MovieClip.onLoad ムービークリップインスタンス化してタイムラインに表示されると、呼び出されます。
  • MovieClip.onMouseDown 左マウスボタンを押すと、呼び出されます。
  • MovieClip.onMouseMove マウスを移動するたびに呼び出されます。
  • MovieClip.onMouseUp 左マウスボタンを離すと、呼び出されます。
  • MovieClip.onPress ポインタがボタン上にあるときにマウスを押すと、呼び出されます。
  • MovieClip.onRelease ポインタがボタン上にあるときにマウスを離すと、呼び出されます。
  • MovieClip.onReleaseOutside ポインタがボタン内にあるときにボタンを押した後で、ポインタがボタン外にあるときにマウスを離すと、呼び出されます。
  • MovieClip.onRollOut ポインタをボタン領域外に移動すると、呼び出されます。
  • MovieClip.onRollOver マウスポインタをボタン上に移動すると、呼び出されます。
  • MovieClip.onSetFocus ボタンにフォーカスがあるときにキーを離すと、呼び出されます。
  • MovieClip.onUnload ムービークリップをタイムラインから削除した後で、最初のフレームで呼び出します。Unload ムービークリップイベントに関連するアクションは、該当するフレームにアクションが割り当てられる前に処理されます。


上のonClipEvent(), on()と比べると……

  • on(@@@)..にあるEventは keyPress("key")以外全部ある。
  • onClipEvent(@@)..にあるEventは全部ある。

ふーん。on(keyPress("key"))..だけないのか。なくてもonKeyDownで代替できるということかな。



FLASH OOP (Advanced Web design books)

FLASH OOP (Advanced Web design books)

  • 作者: FlashOOPJapan
  • 出版社/メーカー: 翔泳社
  • 発売日: 2004-06-16
  • メディア: 単行本

  • おすすめ度の平均: