sample: 2009年9月アーカイブ

 シンボルにもカスタムクラスを関連付けることができます。この手法は先に出版したAS3入門ノートでは解説していましたが、今回の完全改訂版では割愛した内容です。その内容をここで補足したいと思います。

 シンボルからインスタンスを作る方法は「Section07-01 表示オブジェクトの追加」に説明してあるので、ここが補足箇所の候補になりますが(p.211)、この時点ではクラス定義や継承について学んでいません。
 シンボルとカスタムクラスを関連付ける方法はドキュメントクラスと同じ考え方なので、「Section08-06 ドキュメントクラス」の最後のp.486が適当でしょう。ここに以下の原稿を追加します。

シンボルが継承するクラス 追加原稿 p.486
 ドキュメントクラスと同じようにシンボルにもカスタムクラスを関連付けることができます。シンボルにカスタムクラスを関連付けるには、シンボルのプロパティパネルでリンケージ書き出しの設定を行い、クラスフィールドにカスタムクラスを指定します。

fig 08-06-04.jpg
シンボルのリンケージ書き出し設定で関連付けるクラスを指定します

 たとえば、次のFlowerAクラスをシンボルに関連付けると、このシンボルから作ったインスタンスをステージに追加するだけで回転するようになります。このとき、ムービークリップシンボルに関連付けるカスタムクラスは、必ずMovieClipクラスを継承しなければなりません。
 インスタンスはnew FlowerA()で作ることができますが、普通にライブラリからステージにドロップして作ってもかまいません。

[:script:]シンボルに関連付けるFlowerAクラス
package {
	import flash.display.MovieClip;
	import flash.events.Event;

	public class FlowerA extends MovieClip {
		public function FlowerA() {
			addEventListener(Event.ENTER_FRAME, enterFrameHandler );
		}
		protected function enterFrameHandler(eventObj:Event):void {
			rotation += 3;
		}
	}
}

fig 08-06-05.jpg
インスタンスを作ってステージに追加するだけで回転します。→swfを試す
ファイルをダウンロードするextendSymbol.zip

(section04-01 イベントとイベントリスナーから抜粋)

 今度は同じイベントに同じリスナー関数を重ねて追加した場合を見てみましょう。次のサンプルではa_mcのフレーム再生イベントに対してstepRotationA()を4回重ねてリスナー関数として追加しています。この場合にはフレーム再生でstepRotationA()が4回実行されることになり、同じ機能のstepRotationB()を1回しか追加していない場合にb_mcに比べて4倍の速度で回転するでしょうか。
 その結果はa_mcもb_mcと同じくstepRotationA()を1回しか追加していない場合と同じ速度で回転します。すなわち、同じイベントに同じリスナー関数を重ねて追加しても、リスナー関数は重複して登録されないわけです。

[:script:]同じイベントに同じリスナー関数を重ねて追加した場合
//同じイベントに同じリスナー関数を重ねて追加する
a_mc.addEventListener(Event.ENTER_FRAME, stepRotationA);
a_mc.addEventListener(Event.ENTER_FRAME, stepRotationA);
a_mc.addEventListener(Event.ENTER_FRAME, stepRotationA);
a_mc.addEventListener(Event.ENTER_FRAME, stepRotationA);
//b_mcには1度しか追加しない
b_mc.addEventListener(Event.ENTER_FRAME, stepRotationB);

//回転させる
function stepRotationA(eventObj:Event):void {
	a_mc.rotation+=2;
}

function stepRotationB(eventObj:Event):void {
	b_mc.rotation+=2;
}
fig04-01-05.jpg
a_mcもb_mcと同じ速度で回転します。→swfを試す
(section04-01 イベントとイベントリスナーから抜粋)

 同じターゲットの同じイベントに対して複数のリスナーを追加するとどうなるでしょうか。次のスクリプトでは5行目でインスタンスf_mcのEvent.ENTER_FRAMEイベントにstepRotation()をリスナー関数として追加し、次の6行目でも同じくf_mcのEvent.ENTER_FRAMEイベントに今度はstepZoom()をリスナー関数として追加しています。この結果がどうなるかを予想すると、後から実行した6行目のaddEventListener()の設定が5行目のaddEventListener()の設定を上書きしていまい、Event.ENTER_FRAMEイベントではstepZoom()だけが実行されるようになるのではないかと思われます。
 しかし、実際にはEvent.ENTER_FRAMEイベントではstepRotation()とstepZoom()の両方のリスナー関数が実行され、両者の動作が組み合わさったアニメーションになります。すなわち、stepRotation()によって回転し、stepZoom()によって伸縮とアルファ変更を繰り返すアニメーションになります。

[:script:]同じイベントに別のリスナー関数を重ねて追加する
//stepZoomで比率を変化させるための角度
var degree:int;

//同じイベントに別のリスナー関数を重ねて追加する
f_mc.addEventListener(Event.ENTER_FRAME, stepRotation);
f_mc.addEventListener(Event.ENTER_FRAME, stepZoom);

//回転させる
function stepRotation(eventObj:Event):void {
	f_mc.rotation+=2;
}

//伸縮とアルファ変更
function stepZoom(eventObj:Event):void {
	degree=(degree+2)%360;
	//回転角度で比率を変える
	var ratio:Number=Math.abs(Math.sin(degree*Math.PI/180));
	//伸縮
	f_mc.scaleX=f_mc.scaleY=1+9*ratio;
	//アルファ変更
	f_mc.alpha=Math.max(0.02,1-ratio);
}
fig04-01-04b.jpg
回転と伸縮の複数のリスナー関数の動作が組み合わさったアニメーションになります。→swfを試す

 stepZoom()では17行目で比率ratioの値を作っています。sinの値は繰り返しでdegreeに2度ずつ加算され-1〜1のサイン波になり、Math.abs()によって絶対値0〜1で変化する値になります。
 19行目のscaleX、scaleYはインスタンスの横方向、縦方向のスケールを示すプロパティで、1のときが等倍です。この設定値を1+9*ratioで計算しているので、スケールは1倍〜10倍で変化します。21行目のalphaはインスタンスのアルファ値を示すプロパティで、0が透明、1が不透明の0〜1の範囲の値です。この設定値を1-ratioの計算で設定値を変化させ、完全な透明にならないようにMath.max()を使って最低値を0.02に制限しています。
(section04-01 イベントとイベントリスナーから抜粋)

 「インスタンスbox_mcをクリックしたらtest()を実行する」といったインタラクティブな処理を考えたとき、この中には「1.どこで、2.何が起きたら、3.どうする」の3つの要素が含まれています。

 1.どこで 
 2.何が起きたら
 3.どうする 

 これをイベント処理の用語で言い換えると次のようになります。

 1.イベントターゲット ・・・・ イベントが発生するオブジェクト
 2.イベントタイプ ・・・・ 発生するイベントの種類
 3.リスナー関数 ・・・・ イベント発生で実行する関数

 さきほどの「インスタンスbox_mcをクリックしたらtest()を実行する」をこれに当てはめると次のようになります。

 1.イベントターゲット ・・・・ box_mc
 2.イベントタイプ ・・・・ クリック
 3.リスナー関数 ・・・・ test()

 このイベント処理をスクリプトではaddEventListener()というメソッドを使って設定します。書式は次のようになります。イベントが発生するオブジェクトに対して、イベントタイプとリスナー関数をペアにしてイベントリスナーとして追加します。

書式:イベントリスナーを追加する
イベントターゲット.addEventListener(イベントタイプ, リスナー関数);
[:note:] addEventListener()には引数がまだありますが、ここでは省略しています。

 実際のスクリプトは次のようになります。クリックというイベントタイプはMouseEvent.CLICKで指定します。リスナー関数はtestのように()を付けずに指定します。
 実行するtest()も定義しておきます。リスナー関数にはイベントタイプと同じデータ型のイベントオブジェクトが引数として送られてくるので、コンパイルエラーにならないようにtest(eventObj:MouseEvent)のようにイベントオブジェクトを受け取る引数が必要です。

[:script:]box_mcをクリックしたらtest()を実行する
box_mc.addEventListener(MouseEvent.CLICK, test);

//クリックで実行されるリスナー関数
function test(eventObj:MouseEvent):void {
	trace("test OK");
}
 そこで、test()でbox_mcの現在の回転角度つまりbox_mc.rotationに45度を加算すれば、box_mcをクリックするたびにbox_mcが45度回転するようになります。

[:script:]box_mcをクリックすると45度回転する
box_mc.addEventListener(MouseEvent.CLICK, test);

//クリックで実行されるリスナー関数
function test(eventObj:MouseEvent):void {
	//box_mcを45度回転させる
	box_mc.rotation += 45;
}
fig04-01-02.jpgswfを試す
まったく新しいAS3の世界!
694a.jpg
Adobe Flash CS4
詳細!ActionScript3.0入門ノート[完全改訂版](CD-ROM付)

楽しいActionScript。
新たなる1歩へと踏み出しましょう。
■内容は?→ 目次を見る
■評判は?→ 書評を読む
この本を書いたわけ

このアーカイブについて

このページには、2009年9月以降に書かれたブログ記事のうちsampleカテゴリに属しているものが含まれています。

前のアーカイブはsample: 2009年8月です。

次のアーカイブはsample: 2009年10月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

あわせて読みたいブログパーツ