ActionScript 3.0で始めるオブジェクト指向スクリプティング

第24回 インスタンスの管理と配列の並べ替え

この記事を読むのに必要な時間:およそ 7 分

前回の第23回クラスのデザインとループ処理では,EllipticMotionクラスのデザインを将来の拡張も考えて整理し,タイムラインのフレームアクションでは繰返し処理により複数のインスタンスを配置した図1)。

図1 複数のインスタンスが楕円軌道でアニメーションする

図1 複数のインスタンスが楕円軌道でアニメーションする

今回の課題は,まずインスタンスの回転するスピードを,マウスポインタの位置によって変えることにする。つぎに,インスタンスの重ね順を,3次元風の表現に対応するよう修正しよう。

図2 インスタンスの重ね順が3次元風の表現に一部対応していない

図2 インスタンスの重ね順が3次元風の表現に一部対応していない

マウスポインタの位置に応じてインスタンスの回転スビードを変える

まずは,インスタンスが回転するスピードを,マウスポインタの位置によって変えるため,前回のスクリプト2で修正定義したEllipticMotionクラスにもう少し手を加えよう。

今のところ,インスタンスのアニメーションは,コンストラクタメソッドEllipticMotion()の本体で,インスタンスごとのDisplayObject.enterFrameイベント(定数Event.ENTER_FRAME)にリスナー関数rotate()を登録して処理している。

public class EllipticMotion extends MovieClip {
  // ...[中略]...
  public function EllipticMotion(nDegree:Number, myCenter:Point, myRadius:Point) {
  degree = nDegree;
  center = myCenter;
  radius = myRadius;
  addEventListener(Event.ENTER_FRAME, rotate);   // 後に削除
  setRotation();
}

しかし,同じマウスポインタの座標値を,すべてのインスタンスからいちいち確かめるのは効率がよくない。また,のちにインスタンスの重ね順をコントロールする際には,それぞれの仮想の奥行きの値をメインタイムラインから調べる必要がある。

そうだとすれば,タイムラインに配置したインスタンスは,タイムラインのフレームアクションで管理することにしたい。そのうえで,EllipticMotionクラスのrotation()メソッドはタイムラインから呼出し,マウスポインタの座標に応じた回転角の値をその引数として渡そう。

Flashムービー(FLA)ファイルのフレームアクションとして作成した前回のスクリプト3には,タイムラインに配置するEllipticMotionインスタンスが納められるべき配列を新たに変数として宣言し,初期化する。そして,続くforループのコードブロック{}の中で,生成したインスタンスを表示リストに入れるとともに,この配列にも加えることにする。

var instances_array:Array = new Array();   // 追加: 配列を変数として宣言・初期化
for (var i:int = 0; i < nCount; i++) {
  var _mc:EllipticMotion = new EllipticMotion(nDegree * i,myCenter,myRadius);
  addChild(_mc);
  instances_array.push(_mc);   // 追加: 配列にインスタンスを加える
}

これで,タイムラインのフレームアクションで,いつでも配列 (instances_array)からEllipticMotionインスタンスが取出せる。つまり,そのインスタンスを参照して EllipticMotionクラスのrotation()メソッドが呼出せるようになった。そこで,新たな関数rotate()をフレームアクションに定義して,これをタイムラインのDisplayObject.enterFrameイベント(定数Event.ENTER_FRAME)にリスナーとして登録しよう。

var deceleration:Number = 0.1;
// ...[中略]...
addEventListener(Event.ENTER_FRAME, rotate);
function rotate(EventObject:Event):void {   // 追加: リスナー関数
  var nSpeed:Number = (stage.mouseX - myCenter.x)*deceleration;
  var nLength:uint = instances_array.length;
  for (var i:int = 0; i<nLength; i++) {
    var _mc:EllipticMotion = instances_array[i];   // インスタンスの取出し
    _mc.rotate(nSpeed);   // インスタンスのrotate()メソッドを呼出す
  }
}

rotate()関数本体では,マウスポインタのステージ中央からの水平位置に応じた回転角(nSpeed)を求めたうえで,forループの処理によりEllipticMotionインスタンスを配列(instances_array)から順にすべて取出し,その回転角の値を各インスタンスのrotate()メソッドに渡して呼出している※1)。

以上ふたつの修正を加えたフレームアクションが,次のスクリプト1だ。

スクリプト1 マウスポインタの中央からの水平位置に応じてインスタンスの回転スピードを変える

// タイムライン: メイン
var myCenter:Point = new Point(stage.stageWidth / 2, stage.stageHeight / 2);
var myRadius:Point = new Point(100, 50);
var nCount:uint = 6;
var nDegree:Number = 360 / nCount;
var instances_array:Array = new Array();
var deceleration:Number = 0.1;
for (var i:int = 0; i < nCount; i++) {
  var _mc:EllipticMotion = new EllipticMotion(nDegree * i, myCenter, myRadius);
  addChild(_mc);
  instances_array.push(_mc);
}
addEventListener(Event.ENTER_FRAME, rotate);
function rotate(EventObject:Event):void {
  var nSpeed:Number = (stage.mouseX - myCenter.x) * deceleration;
  var nLength:uint = instances_array.length;
  for (var i:int = 0; i < nLength; i++) {
    var _mc:EllipticMotion = instances_array[i];
    _mc.rotate(nSpeed);
  }
}
※1
マウスポインタのステージ中央からの水平位置に応じてアニメーションのスピードを変える処理については,第12回マウスポインタとスクロールの連動を参照してほしい。

著者プロフィール

野中文雄(のなかふみお)

ソフトウェアトレーナー,テクニカルライター,オーサリングエンジニア。上智大学法学部卒,慶応義塾大学大学院経営管理研究科修士課程修了(MBA)。独立系パソコン販売会社で,総務・人事,企画,外資系企業担当営業などに携わる。その後,マルチメディアコンテンツ制作会社に転職。ソフトウェアトレーニング,コンテンツ制作などの業務を担当する。2001年11月に独立。Web制作者に向けた情報発信プロジェクトF-siteにも参加する。株式会社ロクナナ取締役(非常勤)。

URLhttp://www.FumioNonaka.com/

著書

コメント

コメントの記入