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

第57回 インスタンスをクリックした点で回しながらドラッグする

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

まずは,お題をSWFムービーでお見せしよう。というのは,今回では完結せず,残りを次回に持ち越すことになるからだ。目指すコンテンツの動きを,先に確かめてもらいたい。矩形のインスタンスをドラッグすると,回るように動く。マウスを振り回せば,インスタンスがくるくる回る。そして放すと,滑るように減速して,やがて止まる。どこかで見た動きだと感じる読者も少なくないかもしれない。

お題 インスタンスがドラッグで回り放すと滑る(SWF)

課題は大きくふたつある。第1は,初めにマウスクリックした座標で,インスタンスを回すことだ。Matrix3Dクラスを使った3次元空間の回転は,第36回Matrix3Dクラスの後から加える変換で学習した。今回は2次元平面なので,Matrixクラスを使う。もっとも,考え方は基本的に変わらない。

課題の第2は,インスタンスを回す速さはどのように決めたらよいかだ。単純にマウスポインタを動かす速さだけでなく,インスタンスのどこをどの方向にドラッグするかによっても回り方は変わる。実は,ここでベクトルの外積が登場する。ただし,この課題については,次回のお楽しみということになる。

2次元平面のインスタンスを任意の座標で回すには

ということで,今回取組む課題は,クリックした座標でインスタンスを回しながらドラッグすることだ。まずは,Matrixクラスについて簡単に説明しよう。このクラスもMatrix3Dと同じく,行列によりインスタンスの座標を変換する。もちろん,2次元なのでz軸はもたない。行列による座標変換で大切なのは,原点が親タイムラインの基準点になるということだ。

すると,たとえばインスタンスの基準点を中心に変形したいときはどうするか。まず,変換の中心にしたい点が親インスタンスの基準点になるように平行移動する。そのうえでつぎに,変形(伸縮・拡大)を行えば,中心にしたい点(= 親インスタンスの基準点)が原点となって変換される。その後,インスタンスを改めてもとの位置に戻せばよい図1)⁠

図1 親インスタンスの基準点に移動して変形したうえでもとの位置に戻す

(1)親インスタンスの基準点に移動

図1 (1)親インスタンスの基準点に移動

(2)変形(伸縮・回転)

図1 (2)変形(伸縮・回転)

(3)もとの位置に戻す

図1 (3)もとの位置に戻す

それではドラッグは一旦脇に置いて,インスタンスをクリックした座標で回してみよう。使うメソッドは,平行移動がMatrix.translate()回転はMatrix.rotate()になる。Matrix3Dクラスと違い,先に加える変換(prepend)のメソッドはないので,⁠appendをあえてつける必要がなく)メソッド名は端的だ。なお,Matrix.rotate()メソッドの引数に渡す角度は,度数でなくラジアンであることに気をつけてほしい。

Matrixオブジェクト.translate(x座標, y座標)
Matrixオブジェクト.rotate(ラジアン角)

以下のスクリプト1を回したいMovieClipシンボルのフレームアクションに書くと,インスタンスはクリックした座標で回転を始め,マウスボタンを放すまで回り続ける図2)⁠なお,マウスポインタを動かしても,インスタンスの回転の中心はそのまま変わらない。

図2 マウスでプレスした位置を中心にインスタンスが回る

図2 マウスでプレスした位置を中心にインスタンスが回る 図2 マウスでプレスした位置を中心にインスタンスが回る

スクリプト1 マウスプレスした座標でインスタンスを回す

// フレームアクション: マウスプレスした座標で回すMovieClipシンボル
var nX:Number;
var nY:Number;
var angularVelocity:Number = 5 * Math.PI / 180;
addEventListener(MouseEvent.MOUSE_DOWN, xMouseDown);
function xMouseDown(eventObject:MouseEvent):void {
  nX = parent.mouseX;
  nY = parent.mouseY;
  addEventListener(Event.ENTER_FRAME, xDrag);
  stage.addEventListener(MouseEvent.MOUSE_UP, xMouseUp);
}
function xMouseUp(eventObject:MouseEvent):void {
  removeEventListener(Event.ENTER_FRAME, xDrag);
  stage.removeEventListener(MouseEvent.MOUSE_UP, xMouseUp);
}
function xDrag(eventObject:Event):void {
  var myMatrix:Matrix = transform.matrix;
  myMatrix.translate(-nX, -nY);
  myMatrix.rotate(angularVelocity);
  myMatrix.translate(nX, nY);
  transform.matrix = myMatrix;   // Matrixオブジェクトを再設定
}

インスタンスをクリックするInteractiveObject.mouseDownイベント)とリスナー関数(xMouseDown())が呼出され,親インスタンスから見たマウス座標を変数(nXとnY)に記録する。また,インスタンスのDisplayObject.enterFrameイベントに回転のアニメーション(xDrag())⁠StageオブジェクトのInteractiveObject.mouseUpイベントにその停止(xMouseUp())のリスナー関数をそれぞれ登録している。

回転のアニメーションを行うリスナー関数(xDrag())は,まずインスタンスのプロパティDisplayObject.transformからTransform.matrixを参照して,インスタンスに適用されているMatrixオブジェクト(myMatrix)を得る。つぎに,前述のとおり,インスタンスのクリック位置を一旦親インスタンスの基準点に平行移動Matrix.translate()して,そこで回転Matrix.rotate())してから,もとの位置に戻してMatrix.translate()いる。

この座標変換の手順は,基本的にMatrix3Dクラスと変わらない。しかし,最後にひとつ大きく異なる点がある。座標変換を加えたMatrixオブジェクトは,改めてインスタンスのtransform.matrixに設定し直さなければならないことだ。この設定を忘れると,インスタンスは何も変わらない。

著者プロフィール

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

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

URLhttp://www.FumioNonaka.com/

著書

コメント

コメントの記入