サイトトップ

Director Flash 書籍 業務内容 プロフィール

Adobe Flash非公式テクニカルノート

MatrixTransformerクラスによりインスタンスを任意の座標で回す

ID: FN1203002 Product: Flash CS5 and above Platform: All Version: 9.0.28.0 and above/ActionScript 3.0

fl.motion.MatrixTransformerクラスはMatrixオブジェクトを扱う静的メソッドで成立ち、Matrixクラスを補うクラスといえます。本稿では、MatrixTransformerクラスのメソッドを使って、インスタンスを任意の座標で回してみます。


01 Matrixクラスだけでインスタンスを回す
まず、Matrixクラスだけであっても、インスタンスを任意の座標で回すことはできます。インスタンスに適用されているMatrixオブジェクトは、DisplayObject.transformプロパティの参照からTransform.matrixプロパティとして得られます。Matrixは数学の「行列」を意味し、座標の変換を行います。座標変換のためのパラメータ(成分)をもった行列は「変換行列」と呼ばれます[*1]

変換行列による座標変換で注意しなければならないのは、変換の原点が動かせないことです。Matrixクラスで伸縮や回転などの変形を加えると、つねに親インスタンスの基準点が原点になります。[自由変形ツール]でいうなら、中心点が親タイムラインの基準点に固定されるようなものです(図001)。

図001■[自由変形ツール]で親タイムラインの基準点を中心点にする
図002左 図002右

Flashを使い始めたとき、おそらく動かせなくて誰もがつまずくのはシンボルの基準点でしょう。解決方法は、コロンブスの卵でした。基準点が動かないのなら、中身を動かせばよいのです。実は、Matrixクラスでは伸縮や回転のほかに、座標を動かす平行移動という変換ができます。この平行移動を加えると、任意の点を中心にインスタンスを変形できます。

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

図002■親インスタンスの基準点に移動して変形したうえでもとの位置に戻す
図003左
(1)親インスタンスの基準点に移動
図003中央
(2)変形(伸縮・回転)
図003
(3)もとの位置に戻す

それではお題に戻って、インスタンスの基準点を中心とした回転です(図003)。使うメソッドは、平行移動がMatrix.translate()、回転はMatrix.rotate()になります。後者の引数に渡す角度は、度数でなくラジアンであることにお気をつけください。

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

図003■タイムラインに置いたインスタンスを基準点で回す
図001

基準点で回したいMovieClipシンボルに書くフレームアクションは、以下のスクリプト001です。まず、第1〜2行目で、インスタンスのxy座標を変数にとります。これらの値は、インスタンスを親タイムラインの基準点に平行移動するとき使います。つぎに、第3〜4行目は、インスタンスのアニメーションでフレームごとに5度回したいので、メソッドに渡せるようラジアン値に直します。そして、第5行目が、DisplayObject.enterFrameイベント(定数Event.ENTER_FRAME)にリスナー関数(xRotate())を登録します。

インスタンスを基準点で回すのはこのリスナー関数(xRotate())です(スクリプト001第6〜12行目)。もっとも、Matrixクラスによる座標変換の流れは、すでに述べたとおりです。まず、インスタンスに適用されているMatrixオブジェクトを取出します(第7行目)。つぎに、Matrixオブジェクトを親タイムラインの基準点に平行移動し(第8行目)、予め定めた角度回したうえで(第9行目)、平行移動でもとの位置に戻しています(第10行目)。最後に、変換を加えたMatrixオブジェクトは、インスタンスがもつ(DisplayObject.transformプロパティの)Transform.matrixプロパティに設定し直さなければならないことにご注意ください(第11行目)。

スクリプト001■Matrixクラスによりインスタンスを基準点で回す
    // フレームアクション: 基準点で回すMovieClipシンボル
  1. var nX:Number = x;
  2. var nY:Number = y;
  3. var nDegrees:Number = 5;
  4. var nRadians:Number = nDegrees * Math.PI / 180;
  5. addEventListener(Event.ENTER_FRAME, xRotate);
  6. function xRotate(eventObject:Event):void {
  7.   var myMatrix:Matrix = transform.matrix;
  8.   myMatrix.translate(-nX, -nY);
  9.   myMatrix.rotate(nRadians);
  10.   myMatrix.translate(nX, nY);
  11.   transform.matrix = myMatrix;
  12. }

これがMatrixクラスを使ったインスタンスの回し方です。上記スクリプト001をフレームアクションに書いたMovieClipインスタンスは、自らの基準点を中心に回り続けます。

[*1] 変換行列の数学的な説明は「変換行列を数学的に捉える」をお読みください。また、Matrixクラスについては、Adobeデベロッパーセンター「Matrixクラス − 変換行列」を併せてご参照ください。


02 MatrixTransformer.rotateAroundInternalPoint()メソッドでインスタンスを回す
静的メソッドMatrixTransformer.rotateAroundInternalPoint()を使うと、引数に指定したxy座標でMatrixオブジェクトが回転できます。第1引数には変換するMatrixオブジェクトを渡します。第2および第3引数に、インスタンスから見たxy座標を定めます。そして、第4引数の回転角は度数です。

MatrixTransformer.rotateAroundInternalPoint(Matrixオブジェクト, x座標, y座標, 度数角)

インスタンスから見たインスタンスの基準点は、つねに座標(0, 0)です。すると、前掲スクリプト001は、MatrixTransformer.rotateAroundInternalPoint()メソッドを使えばつぎのスクリプト002のようにすっきりと書替わります。

スクリプト002■MatrixTransformer.rotateAroundInternalPoint()メソッドによりインスタンスを基準点で回す
    // フレームアクション: 基準点で回すMovieClipシンボル
  1. var nDegrees:Number = 5;
  2. addEventListener(Event.ENTER_FRAME, xRotate);
  3. function xRotate(eventObject:Event):void {
  4.   var myMatrix:Matrix = transform.matrix;
  5.   MatrixTransformer.rotateAroundInternalPoint(myMatrix, 0, 0, nDegrees);
  6.   transform.matrix = myMatrix;
  7. }

では応用として、インスタンスをプレスつまりマウスボタンを押し続けたら初めにクリックした座標で回り続け、マウスボタンを放したらアニメーションは止めるようにしてみましょう。以下のスクリプト003が、マウスプレスした座標で回すMovieClipシンボルに書くフレームアクションです。

インスタンスの上でマウスボタンを押すと(定数MouseEvent.MOUSE_DOWN)、リスナー関数(xStart)が呼出されます(第4〜10行目)。この関数は、クリックしたマウス座標を変数に覚え(第6〜7行目)、前掲スクリプト002と同じようにインスタンス回転のリスナー関数(xRotate())をDisplayObject.enterFrameイベントに登録しています(第8行目)。そして、マウスボタンを放したとき(定数MouseEvent.MOUSE_UP)のために、アニメーション停止のイベントリスナー(xStop())が加えられます(第9行目)。

インスタンスを回転するリスナー関数(xRotate())のやっていることは(第11〜15行目)、基本的に前掲スクリプト002(第3〜7行目)と変わりません。ただ、MatrixTransformer.rotateAroundInternalPoint()メソッドに渡す回転の中心座標が、初めにインスタンスをクリックした位置の変数値(nXとnY)だという違いがあるだけです(第13行目)。

マウスボタンを放すと、リスナー関数(xStop())が呼出されます(第16〜19行目)。そして、アニメーションの関数(xRotate())と自身を、それぞれイベントリスナーから除きます。

スクリプト003■マウスプレスした座標でインスタンスを回す
    // フレームアクション: マウスプレスした座標で回すMovieClipシンボル
  1. var nX:Number = 0;
  2. var nY:Number = 0;
  3. var nDegrees:Number = 5;
  4. addEventListener(MouseEvent.MOUSE_DOWN, xStart);
  5. function xStart(eventObject:MouseEvent):void {
  6.   nX = mouseX;
  7.   nY = mouseY;
  8.   addEventListener(Event.ENTER_FRAME, xRotate);
  9.   stage.addEventListener(MouseEvent.MOUSE_UP, xStop);
  10. }
  11. function xRotate(eventObject:Event):void {
  12.   var myMatrix:Matrix = transform.matrix;
  13.   MatrixTransformer.rotateAroundInternalPoint(myMatrix, nX, nY, nDegrees);
  14.   transform.matrix = myMatrix;
  15. }
  16. function xStop(eventObject:MouseEvent):void {
  17.   removeEventListener(Event.ENTER_FRAME, xRotate);
  18.   stage.removeEventListener(MouseEvent.MOUSE_UP, xStop);
  19. }

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

03 MatrixTransformer.rotateAroundExternalPoint()メソッドでインスタンスを回す
MatrixTransformerクラスには、指定した座標でMatrixオブジェクトを回転する静的メソッドとして、もうひとつMatrixTransformer.rotateAroundExternalPoint()があります。MatrixTransformer.rotateAroundInternalPoint()との違いは、メソッドに渡す第2および第3引数が親から見たxy座標になることです[*2]。

MatrixTransformer.rotateAroundExternalPoint(Matrixオブジェクト, 親空間のx座標, 親空間のy座標, 度数角)

前掲スクリプト003は、このMatrixTransformer.rotateAroundExternalPoint()を使って書替えることもできます。つぎのスクリプト004のとおり、メソッドの引数に渡す中心座標(第13行目)を親から見た座標に変えるだけです(第6および第7行目)。

スクリプト004■マウスプレスした座標でインスタンスを回す − 親座標空間から捉える
    // フレームアクション: マウスプレスした座標で回すMovieClipシンボル
  1. var nX:Number = 0;
  2. var nY:Number = 0;
  3. var nDegrees:Number = 5;
  4. addEventListener(MouseEvent.MOUSE_DOWN, xStart);
  5. function xStart(eventObject:MouseEvent):void {
  6.   nX = parent.mouseX;
  7.   nY = parent.mouseY;
  8.   addEventListener(Event.ENTER_FRAME, xRotate);
  9.   stage.addEventListener(MouseEvent.MOUSE_UP, xStop);
  10. }
  11. function xRotate(eventObject:Event):void {
  12.   var myMatrix:Matrix = transform.matrix;
  13.   MatrixTransformer.rotateAroundExternalPoint(myMatrix, nX, nY, nDegrees);
  14.   transform.matrix = myMatrix;
  15. }
  16. function xStop(eventObject:MouseEvent):void {
  17.   removeEventListener(Event.ENTER_FRAME, xRotate);
  18.   stage.removeEventListener(MouseEvent.MOUSE_UP, xStop);
  19. }

[*2] [ヘルプ]の[MatrixTransformer]で「rotateAroundExternalPoint()メソッド」を見ると、つぎのように説明されています。

マトリックスの変換空間外に定義されたポイントを軸としてマトリックスを回転します。これにより、親内の変換ポイントを軸としてムービークリップを回転させることができます。

「変換空間外」という書き方を見ると、座標空間が指定できそうにも読めます。けれど、座標空間を決めるインスタンスが渡せませんので、「親内の変換ポイント」つまり親の座標空間にもとづく変換にかぎられます。


作成者: 野中文雄
作成日: 2012年3月11日


Copyright © 2001-2012 Fumio Nonaka.  All rights reserved.