cocos2dのジェスチャー検出はUIGestureRecognizerという素晴らしいクラスが用意されており、検出ロジックには全く触れずにコーディングできた。が!AndEngineに移植するにあたって、いろいろ調べたが、大体、自前で実装しているらしいことがわかり、やむなくコーディング開始した。
シングルタップのスワイプは以下のような実装でいいとおもう。
@Override public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { float x = pSceneTouchEvent.getX(); float y = pSceneTouchEvent.getY(); long n_time = System.currentTimeMillis(); switch(pSceneTouchEvent.getAction()){ case TouchEvent.ACTION_DOWN:{ f_x = x; f_y = y; s_time = n_time; break; } case TouchEvent.ACTION_UP:{ float dy = f_y - y; long dt = n_time - s_time; float speed = dy*1000/dt; if((speed>=SWIPE_SPEED_MIN)&&(dy>=SWIPE_MOVE_MIN)){ //ここで垂直スワイプの検出 } break; } } return true; }
s_timeとn_timeでスワイプ時間を計測し、スワイプスピードと距離を算出。SWIPE_SPEED_MINとSWIPE_MOVE_MINにスワイプ認識の固定値をいれて検出という仕組み。
ローテーションジェスチャーの場合はこうもいかない。じつは、マルチタッチ時にくる座標は、指の数はわかるものの、どの指が、どの座標かという情報は一切ない。ので、それを判別するコードを書き加える必要がある。
①2指でのローテーションの場合、TouchEvent.ACTION_DOWNで、「2指の距離」をまず判別し、次に適正な距離であれば、「2点が対象スプライト内部にある」or「2点の中点がスプライト内にある」を基にして対象スプライトを特定する。
②対象スプライトの特定が終われば、TouchEvent.ACTION_MOVEで、ローテーション時に送られてくる座標(2指どっちかは不明)を、どっちの指かを判断するためにTouchEvent.ACTION_DOWN時の座標からの距離で判定する(これでいいかはわからないけども)。
③2指の「なす角度」とTouchEvent.ACTION_MOVE時の2点の「なす角度」の差をローテーション角度としてセットする。
をコード化する必要がある。コードはあるんだけど・・・いろんなジェスチャー検出のためにごっちゃになっています。整理しだいコードを上げます。が、①~③で、おおむね動いています。