ActionScript 3.0で始めるオブジェクト指向スクリプティング
第11回 MovieClipをスクロールさせる―条件判定
サムネールを水平に並べてスクロールさせるメニューのインターフェイスがある(図1)。スクロールする方向やスピードは,マウスポインタの位置によって変わる。今回と次回の2回にわたって,このようなMovieClipのアニメーションをつくってみたい。今回のポイントは,条件を判定して分岐する処理の書き方だ。
ループする水平スクロール―ifステートメント
まずは,これまでの復習として,毎フレーム5ピクセルで水平方向右に単純にスクロールするMovieClipのフレームアクションを書いてみよう(スクリプト1)。スクリプトを書くときは,いきなり目的の動作を実現しようとするのでなく,処理を小分けにして段階的に進めていくことが大切だ。
上級者でも,ひとつのミスもなく,1回で動きを完成することはたやすくない。小分けにして作成と確認を繰返していけば,問題が出たときも,その調査対象を限定できる。事件の早期解決には,何より容疑者の絞り込みが重要なのだ。
スクリプト1 MovieClipインスタンスを水平スクロールさせる
// MovieClip: スクロールさせるインスタンス
var nSpeed:Number = 5;
addEventListener(Event.ENTER_FRAME, xScroll);
function xScroll(eventObject:Event):void {
x += nSpeed;
}
毎フレームの描画更新は,DisplayObject.enterFrameイベントで受取る。MovieClipインスタンスにこのイベントのリスナー関数を登録して,関数内では初期値として定めたピクセル数をインスタンスのDisplayObject.xプロパティに代入している(図2)。このアニメーションの処理については,これ以上説明の必要はあるまい。
次は,ステージ右端を超えたら,左端にループしてスクロールを続ける処理だ。インスタンスの水平座標がステージ右端を超えたかどうかの条件を判定する必要がある。ここで,ifステートメントを使う。シンタックスは,次のとおりだ。
if (条件) {
// 条件が満たされた場合の処理
}
今回の条件は,インスタンスのDisplayObject.xプロパティの値が,ステージ右端の座標値つまりStage.stageWidthを超えたかどうかである。
この条件を表す式は,数学の時間に習った不等式と同じく,不等号(<,>)で表す。等しい場合を含めるときは,等号を右に添える(<=,>=)。注意しなければならないのは,両辺の値が等しいこと(等価)を示すには,等価演算子(==)が用いられることだ。ActionScriptでは,等号(=)は代入の演算子として区別される。
MovieClipインスタンスの水平座標がステージ右端を超え,if条件が満たされたなら,インスタンスを左端に移動する。ステージ左端の水平座標は,もちろん0である。すると,条件判定のifステートメントは,次のように記述すればよさそうに思える。
if (x>stage.stageWidth) { // ステージ右端を超えたら
x = 0; // ステージ左端に移動
}
実際,[ムーピープレビュー]を確かめると,ステージ右端を超えたインスタンスは,また左端から現れてスクロールを続ける(図3)。アニメーションが,インスタンスひとつであれば,差支えはないかもしれない。しかし,並べてスクロールすると,問題が明らかになる。
なぜなら,ステージ右端からはみ出すピクセル数は,インスタンスによって最小1ピクセルから最大5ピクセルまで異なる可能性がある(図4)。そのピクセル数に関係なく,インスタンスをステージ左端の水平座標0に移動すると,インスタンス同士の間隔が変わってしまう。つまり,ステージ右端を1ピクセルだけ超えて0ピクセルに移動したインスタンスは,5ピクセル超えてようやく0ピクセルにループしたインスタンスより4ピクセル早く進むことができ,後続のインスタンスとは間隔が開いてしまうのである。
インスタンスの間隔を変えないためには,一律に同じ座標に移すのではなく,一定の距離左に移動すればよい。つまり,水平座標からステージ幅を差引くのである。現在値から数値を差引くときは,演算子-=を用いる。
前述スクリプト1にこの条件判定の処理を加えたのが,以下のスクリプト2である。
スクリプト2 インスタンスがステージ右端を超えたらステージ幅分左に移動
// MovieClip: スクロールさせるインスタンス
var nSpeed:Number = 5;
var nStageLeft:Number = 0;
var nStageRight:Number = stage.stageWidth;
var nStageWidth:Number = nStageRight-nStageLeft;
addEventListener(Event.ENTER_FRAME, xScroll);
function xScroll(eventObject:Event):void {
x += nSpeed;
if (x>nStageRight) { // ステージ右端を超えたら
x -= nStageWidth; // ステージ左端に移動
}
}



