3.0Starlingフレームワークでは、マウスイベントはDisplayObject.touchイベント(定数TouchEvent.TOUCH)で扱います。本稿は、DisplayObject.touchイベントを使ったインスタンスのドラッグ&ドロップのやり方についてご説明します。Quadインスタンスをステージに置くまずは、ドラッグするインスタンスをステージに置かなければなりません。矩形のQuadインスタンスをひとつつくることにします。Starlingフレームワークのルートクラス(MySprite)はつぎのように定めます。ステートメントの頭に添えた番号は、後に掲げるドラッグ&ドロップまでつくり込んだクラス定義のスクリプト001の行を示します。2;}}}そして、クラス定義のASファイルと同じ場所に保存したFlashムービー(FLA)ファイルには、メインタイムラインにつぎのフレームアクションが書かれているものとします。[パブリッシュプレビュー]で確かめると、ステージに50ピクセル四方の青い矩形のQuadインスタンスが表れます(図001)。stage);myStarling.start();図001■ステージに矩形のQuadインスタンスを置くこれらのスクリプトの内容およびパブリッシュ設定などのStarlingフレームワークを使うために必要な準備については、基本的に「Starlingフレームワークを使う」でご説明しています。詳しくは、このノートをお読みください。ドラッグ&ドロップのために用いるイベントおよびプロパティとメソッドマウスのインタラクティブな操作は、DisplayObject.touchイベントで扱われます。どのような操作をマウスでしたのかは、DisplayObject.touchイベントのリスナーが引数に受取るTouchEventオブジェクトからTouchEvent.getTouch()メソッドによりTouchオブジェクトを得て、そのTouch.phaseプロパティで調べます[*1]。Touch.phaseプロパティがとる文字列の値は、TouchPhaseクラスに定数として定められています。Touchクラスという名前からもおわかりのように、マウスだけでなくタッチスクリーンのインタラクションも同じように扱えます。TouchPhaseクラスの定数とタッチスクリーンおよびマウスの操作は、次表001のとおりです。ボタンを押したままマウスは動かさないマウスのドラッグに当たるTouch.phaseプロパティの値は、TouchPhase.MOVEDです。Flashに定義済みのInteractiveObject.mouseMoveイベント(定数MouseEvent.MOUSE_MOVE)と違って、インスタンスの上でマウスボタンは押したまま動かしていることを示します。この値だけでドラッグが捉えられ、別にマウスボタンを押したか放したかは調べずに済むのです。Touch.phaseプロパティを調べるには、Touchオブジェクトを得なければなりません。DisplayObject.touchイベントのリスナーが受取ったTouchEventオブジェクトからTouchオブジェクトを取出すのはTouchEvent.getTouch()メソッドです。引数はふたつあります。TouchPhaseクラス定数)第1引数は、DisplayObject.touchイベントの受取りを調べる表示リストの頂点となるDisplayObjectインスタンスです。TouchEvent.getTouch()メソッドは、この引数に定めたインスタンスとその表示リスト下層の子インスタンスからTouchオブジェクトを探します。第2引数のTouchPhaseクラス定数で、DisplayObject.touchイベントの操作を絞り込めます。デフォルト値はnullで、すべてのDisplayObject.touchイベントになります。ふたつの引数で定まるTouchオブジェクトが見つかればそのオブジェクト、なければnullが返ります。DisplayObject.touchイベントを扱うリスナーは、EventDispatcher.addEventListener()メソッドで決まります。それに、TouchEvent.getTouch()メソッドの第2引数を組合わせれば、第1引数を絞り込まなければならないことは多くありません。その場合、第1引数は表示リスト最上位のStageオブジェクトを渡します。インスタンスをドラッグするためには、DisplayObject.touchイベントが起こったときのマウスポインタの座標を知りたいです。Touch.getLocation()メソッドは、その座標をPointオブジェクトで返します。引数のDisplayObjectインスタンスが、座標空間を定めます。クラス」が参考になります。インスタンスをドラッグ&ドロップするスクリプトステージに置いたQuadインスタンスをドラッグ&ドロップするStarlingルートクラス(MySprite)の定義は以下のスクリプト001のとおりです。必要なクラスのimport宣言(第7〜9行目)をしたうえで、QuadインスタンスのDisplayObject.touchイベントにリスナーメソッド(dispatchMouseEvent())を加えます(第23行目)。つぎに、リスナーメソッド(dispatchMouseEvent())はさまざまなマウス操作を同じDisplayObject.touchイベントとして受取るため、操作に応じたメソッドは別に定めることにして交通整理に徹しました。TouchEvent.getTouch()メソッドでドラッグ操作(定数TouchPhase.MOVED)のTouchオブジェクトを取出し(第33行目)、オブジェクトがあればドラッグ用のメソッドを呼出します(第34〜36行目)。ドラッグ用のメソッド(onMouseMove())は、マウス操作が加えられたインスタンスをEvent.currentTargetプロパティで取出し(第26行目)、またTouchEvent.getTouch()メソッドでTouchオブジェクト(第27行目)、Touch.getLocation()メソッドで操作が加わったマウス座標(第28行目)を得ています。そのうえで、ドラッグするインスタンスの位置を、マウス座標に合わせます(第29〜30行目)。{onMouseMove(eventObject);}}}}これでステージのQuadインスタンスがドラッグドロップできます。細かい動きでひとつ気になります。インスタンスの端でクリックしても、ドラッグし始めるとポインタがインスタンスの原点(基準点)にきてしまうことです(図002)。次項で、この問題を直しましょう。マウスポインタが移動した座標を調べるインスタンス上でドラッグし始めたマウスポインタの位置を保つということは、Flashコンテンツのドラッグ操作でよく行われます。マウスポインタとインスタンスの座標の差をオフセットとして覚えておき、ドラッグするインスタンスの位置をその分ずらすというのがお決まりです。ところが、Touchオブジェクトを使うと、初めに座標の差を求める手間が省けます。それは、Touchオブジェクトそのものが、ひとつ前のDisplayObject.touchイベントのときのマウス座標を覚えているからです。その座標のPointオブジェクトが、Touch.getPreviousLocation()メソッドで得られます。座標がひとつ古いというだけで、使い方はTouch.getLocation()メソッドと同じです。Touchオブジェクト.getPreviousLocation(DisplayObjectオフジェクト)前掲スクリプト001で、手を加えるのはドラッグ用のメソッド(onMouseMove())です。でき上がりはスクリプト002として後に掲げました。その中からドラッグ用のメソッドを抜書きすると、つぎのとおりです(行番号は後掲スクリプト002にもとづきます)。movePoint.y;}Touch.getPreviousLocation()メソッドでひとつ前のイベントのときのマウスポインタの座標を調べ(第29行目)、現在のポインタの座標との差をPoint.subtract()メソッドにより求めたうえで(第30行目)、Quadインスタンスの位置をその座標の変化に合わせて動かしています(第31〜32行目)。このご説明ですっきりおわかりになれば結構です。戸惑っている方も少なくないでしょう。いうのは、前掲スクリプト001と、細かいところがあちこち変わっているからです。スクリプト001はTouch.getLocation()メソッドの引数に親インスタンス(DisplayObject.parentプロパティ)を渡していました。ところが、スクリプト002では、Touch.getPreviousLocation()メソッドとともに、ドラッグされるインスタンス自身が引数になっています(第28〜29行目)。+=(スクリプト002第31〜32行目)です。それはスクリプト002が、前掲スクリプト001と座標の捉え方を変えたためです。スクリプト001は、マウスポインタの座標を調べて、インスタンスをその位置に動かしました。スクリプト002は、マウスポインタの座標がどこにあるかは気にしません。ポインタがどれだけ動いたかの差を求め、インスタンスにマウスポインタと同じ動きをさせているだけなのです[*2]。結果として、マウスポインタとインスタンスとの座標の差(ずれ)が保たれるのです(図003)。したがって、Touch.getLocation()およびTouch.getPreviousLocation()メソッドに渡す引数のオブジェクトは、スクリプト001と同じく親インスタンスでも構いません。どちらのインスタンスから見ても、マウスポインタの座標の動きは変わらないからです。