Jelajahi Sumber

Add new gestures (Long Tap, Drag, Drop)
Add new gestures support for android

SAUVAGEOT Paul-Arthur 12 tahun lalu
induk
melakukan
14aceba8fd

+ 12 - 0
gameplay/src/Game.cpp

@@ -517,6 +517,18 @@ void Game::gestureTapEvent(int x, int y)
 {
 }
 
+void Game::gestureLongTapEvent(int x, int y, float duration)
+{
+}
+
+void Game::gestureDragEvent(int x, int y)
+{
+}
+
+void Game::gestureDropEvent(int x, int y)
+{
+}
+
 void Game::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad)
 {
 }

+ 42 - 17
gameplay/src/Game.h

@@ -27,7 +27,7 @@ class ScriptController;
 class Game
 {
     friend class Platform;
-	friend class ShutdownListener;
+    friend class ShutdownListener;
 
 public:
     
@@ -440,6 +440,15 @@ public:
      */
     virtual void gesturePinchEvent(int x, int y, float scale);
 
+    /**
+     * Gesture callback on Gesture::LONG_TAP events.
+     *
+     * @param x The x-coordinate of the long tap.
+     * @param y The y-coordinate of the long tap.
+     * @param duration The duration of the long tap in ms.
+     */
+    virtual void gestureLongTapEvent(int x, int y, float duration);
+
     /**
      * Gesture callback on Gesture::TAP events.
      *
@@ -448,6 +457,22 @@ public:
      */
     virtual void gestureTapEvent(int x, int y);
 
+    /**
+     * Gesture callback on Gesture::DRAG events.
+     *
+     * @param x The x-coordinate of the start of the drag event.
+     * @param y The y-coordinate of the start of the drag event.
+     */
+    virtual void gestureDragEvent(int x, int y);
+
+    /**
+     * Gesture callback on Gesture::DROP events.
+     *
+     * @param x The x-coordinate of the drop event.
+     * @param y The y-coordinate of the drop event.
+     */
+    virtual void gestureDropEvent(int x, int y);
+
     /**
      * Gamepad callback on gamepad events.  Override to receive Gamepad::CONNECTED_EVENT 
      * and Gamepad::DISCONNECTED_EVENT, and store the Gamepad* in order to poll it from update().
@@ -482,18 +507,18 @@ public:
     inline Gamepad* getGamepad(unsigned int index, bool preferPhysical = true) const;
 
     /**
-	 * Sets whether multi-sampling is to be enabled/disabled. Default is disabled.
-	 *
-	 * @param enabled true sets multi-sampling to be enabled, false to be disabled.
-	 */
-	inline void setMultiSampling(bool enabled);
+     * Sets whether multi-sampling is to be enabled/disabled. Default is disabled.
+     *
+     * @param enabled true sets multi-sampling to be enabled, false to be disabled.
+     */
+    inline void setMultiSampling(bool enabled);
 
-	/*
-	 * Is multi-sampling enabled.
-	 *
-	 * @return true if multi-sampling is enabled.
-	 */
-	inline bool isMultiSampling() const;
+    /*
+     * Is multi-sampling enabled.
+     *
+     * @return true if multi-sampling is enabled.
+     */
+    inline bool isMultiSampling() const;
 
     /**
      * Sets multi-touch is to be enabled/disabled. Default is disabled.
@@ -671,10 +696,10 @@ private:
         std::string function;
     };
 
-	struct ShutdownListener : public TimeListener
-	{
-		void timeEvent(long timeDiff, void* cookie);
-	};
+    struct ShutdownListener : public TimeListener
+    {
+        void timeEvent(long timeDiff, void* cookie);
+    };
 
     /**
      * TimeEvent represents the event that is sent to TimeListeners as a result of calling Game::schedule().
@@ -746,7 +771,7 @@ private:
     AudioListener* _audioListener;              // The audio listener in 3D space.
     std::priority_queue<TimeEvent, std::vector<TimeEvent>, std::less<TimeEvent> >* _timeEvents;     // Contains the scheduled time events.
     ScriptController* _scriptController;            // Controls the scripting engine.
-    SocialController* _socialController;		// Controls social aspect of the game.
+    SocialController* _socialController;        // Controls social aspect of the game.
     std::vector<ScriptListener*>* _scriptListeners; // Lua script listeners.
 
     // Note: Do not add STL object member variables on the stack; this will cause false memory leaks to be reported.

+ 3 - 0
gameplay/src/Gesture.h

@@ -19,6 +19,9 @@ public:
         GESTURE_TAP = 0,
         GESTURE_SWIPE,
         GESTURE_PINCH,
+        GESTURE_LONG_TAP,
+        GESTURE_DRAG,
+        GESTURE_DROP,
         GESTURE_ANY_SUPPORTED = -1,
     };
 

+ 21 - 0
gameplay/src/Platform.cpp

@@ -63,6 +63,27 @@ void Platform::gestureTapEventInternal(int x, int y)
     Game::getInstance()->getScriptController()->gestureTapEvent(x, y);
 }
 
+void Platform::gestureLongTapEventInternal(int x, int y, float duration)
+{
+    // TODO: Add support to Form for gestures
+	Game::getInstance()->gestureLongTapEvent(x, y, duration);
+	Game::getInstance()->getScriptController()->gestureLongTapEvent(x, y, duration);
+}
+
+void Platform::gestureDragEventInternal(int x, int y)
+{
+    // TODO: Add support to Form for gestures
+	Game::getInstance()->gestureDragEvent(x, y);
+	Game::getInstance()->getScriptController()->gestureDragEvent(x, y);
+}
+
+void Platform::gestureDropEventInternal(int x, int y)
+{
+    // TODO: Add support to Form for gestures
+	Game::getInstance()->gestureDropEvent(x, y);
+	Game::getInstance()->getScriptController()->gestureDropEvent(x, y);
+}
+
 void Platform::resizeEventInternal(unsigned int width, unsigned int height)
 {
     // Update the width and height of the game

+ 21 - 0
gameplay/src/Platform.h

@@ -336,6 +336,27 @@ public:
      */
     static void gestureTapEventInternal(int x, int y);
 
+    /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+	static void gestureLongTapEventInternal(int x, int y, float duration);
+
+    /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+	static void gestureDragEventInternal(int x, int y);
+
+    /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+	static void gestureDropEventInternal(int x, int y);
+
     /**
      * Internal method used only from static code in various platform implementation.
      *

+ 65 - 8
gameplay/src/PlatformAndroid.cpp

@@ -51,11 +51,15 @@ PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays = NULL;
 PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays = NULL;
 PFNGLISVERTEXARRAYOESPROC glIsVertexArray = NULL;
 
-#define GESTURE_TAP_DURATION_MAX    200
-#define GESTURE_SWIPE_DURATION_MAX  400
-#define GESTURE_SWIPE_DISTANCE_MIN  50
+#define GESTURE_TAP_DURATION_MAX        200
+#define GESTURE_LONG_TAP_DURATION_MIN    GESTURE_TAP_DURATION_MAX
+#define    GESTURE_DRAG_START_DURATION_MIN    GESTURE_LONG_TAP_DURATION_MIN
+#define GESTURE_DRAG_DISTANCE_MIN    10
+#define GESTURE_SWIPE_DURATION_MAX      400
+#define GESTURE_SWIPE_DISTANCE_MIN      50
 
-static std::bitset<3> __gestureEventsProcessed;
+static bool    __gestureDraging = false;
+static std::bitset<6> __gestureEventsProcessed;
 
 struct TouchPointerData
 {
@@ -72,6 +76,7 @@ TouchPointerData __pointer1;
 namespace gameplay
 {
 
+
 static double timespec2millis(struct timespec *a)
 {
     GP_ASSERT(a);
@@ -555,6 +560,7 @@ static Keyboard::Key getKey(int keycode, int metastate)
             return Keyboard::KEY_MENU;
         case AKEYCODE_SEARCH:
             return Keyboard::KEY_SEARCH;
+    
         case AKEYCODE_BACK:
             return Keyboard::KEY_ESCAPE;
         default:
@@ -732,9 +738,19 @@ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
                     {
                         int deltaX = x - __pointer0.x;
                         int deltaY = y - __pointer0.y;
-
+                        // Test for drop
+                        if (__gestureDraging)
+                        {
+                            if (__gestureEventsProcessed.test(Gesture::GESTURE_DROP))
+                            {
+                                gameplay::Platform::gestureDropEventInternal(x, y);
+                                __pointer0.pressed = false;
+                                gestureDetected = true;
+                            }
+                            __gestureDraging = false;
+                        }
                         // Test for swipe
-                        if (__gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) &&
+                        else if (__gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) &&
                             gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time < GESTURE_SWIPE_DURATION_MAX && 
                             (abs(deltaX) > GESTURE_SWIPE_DISTANCE_MIN || abs(deltaY) > GESTURE_SWIPE_DISTANCE_MIN) )
                         {
@@ -757,6 +773,7 @@ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
                             __pointer0.pressed = false;
                             gestureDetected = true;
                         }
+                        // Test for tap
                         else if(__gestureEventsProcessed.test(Gesture::GESTURE_TAP) &&
                                gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time < GESTURE_TAP_DURATION_MAX)
                         {
@@ -764,6 +781,14 @@ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
                             __pointer0.pressed = false;
                             gestureDetected = true;
                         }
+                        // Test for long tap
+                        else if(__gestureEventsProcessed.test(Gesture::GESTURE_LONG_TAP) &&
+                               gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time >= GESTURE_LONG_TAP_DURATION_MIN)
+                        {
+                            gameplay::Platform::gestureLongTapEventInternal(x, y, gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time);
+                            __pointer0.pressed = false;
+                            gestureDetected = true;
+                        }    
                     }
 
                     if (!gestureDetected && (__multiTouch || __primaryTouchId == pointerId) )
@@ -841,6 +866,13 @@ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
                             __pointer1.pressed = false;
                             gestureDetected = true;
                         }
+                        else if(__gestureEventsProcessed.test(Gesture::GESTURE_LONG_TAP) &&
+                               gameplay::Game::getInstance()->getAbsoluteTime() - __pointer1.time >= GESTURE_LONG_TAP_DURATION_MIN)
+                        {
+                            gameplay::Platform::gestureLongTapEventInternal(x, y, gameplay::Game::getInstance()->getAbsoluteTime() - __pointer1.time);
+                            __pointer1.pressed = false;
+                            gestureDetected = true;
+                        }    
                     }
 
                     if (!gestureDetected && (__multiTouch || __primaryTouchId == pointerId) )
@@ -859,7 +891,25 @@ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
                     for (size_t i = 0; i < pointerCount; ++i)
                     {
                         pointerId = AMotionEvent_getPointerId(event, i);
-                        if (__multiTouch || __primaryTouchId == pointerId)
+                        x = AMotionEvent_getX(event, i);
+                        y = AMotionEvent_getY(event, i);
+                        
+                        bool gestureDetected = false;
+                        if (__pointer0.pressed && __pointer0.pointerId == pointerId)
+                        {
+                            int deltaX = x - __pointer0.x;
+                            int deltaY = y - __pointer0.y;
+                            
+                            if (__gestureDraging == true || __gestureEventsProcessed.test(Gesture::GESTURE_DRAG) && 
+                                 gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time >= GESTURE_DRAG_START_DURATION_MIN &&
+                                abs(deltaX) >= GESTURE_DRAG_DISTANCE_MIN && abs(deltaY) >= GESTURE_DRAG_DISTANCE_MIN)
+                            {
+                                gameplay::Platform::gestureDragEventInternal(x, y);
+                                __gestureDraging = true;
+                                gestureDetected = true;
+                            }
+                        }
+                        if (!gestureDetected && (__multiTouch || __primaryTouchId == pointerId))
                         {
                             gameplay::Platform::touchEventInternal(Touch::TOUCH_MOVE, AMotionEvent_getX(event, i), AMotionEvent_getY(event, i), pointerId);
                         }
@@ -1342,7 +1392,8 @@ void Platform::shutdownInternal()
 bool Platform::isGestureSupported(Gesture::GestureEvent evt)
 {
     // Pinch currently not implemented
-    return evt == gameplay::Gesture::GESTURE_SWIPE || evt == gameplay::Gesture::GESTURE_TAP;
+    return evt == gameplay::Gesture::GESTURE_SWIPE || evt == gameplay::Gesture::GESTURE_TAP || evt == gameplay::Gesture::GESTURE_LONG_TAP ||
+        evt == gameplay::Gesture::GESTURE_DRAG || evt == gameplay::Gesture::GESTURE_DROP;
 }
 
 void Platform::registerGesture(Gesture::GestureEvent evt)
@@ -1355,6 +1406,9 @@ void Platform::registerGesture(Gesture::GestureEvent evt)
 
     case Gesture::GESTURE_TAP:
     case Gesture::GESTURE_SWIPE:
+    case Gesture::GESTURE_LONG_TAP:
+    case Gesture::GESTURE_DRAG:
+    case Gesture::GESTURE_DROP:
         __gestureEventsProcessed.set(evt);
         break;
 
@@ -1373,6 +1427,9 @@ void Platform::unregisterGesture(Gesture::GestureEvent evt)
 
     case Gesture::GESTURE_TAP:
     case Gesture::GESTURE_SWIPE:
+    case Gesture::GESTURE_LONG_TAP:
+    case Gesture::GESTURE_DRAG:
+    case Gesture::GESTURE_DROP:
         __gestureEventsProcessed.set(evt, 0);
         break;
 

+ 12 - 0
gameplay/src/ScriptController.cpp

@@ -873,6 +873,18 @@ void ScriptController::gestureTapEvent(int x, int y)
         executeFunction<void>(list[i].c_str(), "ii", x, y);
 }
 
+void ScriptController::gestureLongTapEvent(int x, int y, float duration)
+{
+}
+
+void ScriptController::gestureDragEvent(int x, int y)
+{
+}
+
+void ScriptController::gestureDropEvent(int x, int y)
+{
+}
+
 void ScriptController::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex)
 {
     std::vector<std::string>& list = _callbacks[GAMEPAD_EVENT];

+ 25 - 0
gameplay/src/ScriptController.h

@@ -901,6 +901,31 @@ private:
      */
     void gestureTapEvent(int x, int y);
 
+	/**
+	 * Gesture callback on Gesture::LONG_TAP events.
+	 *
+	 * @param x The x-coordinate of the long tap.
+	 * @param y The y-coordinate of the long tap.
+	 * @param duration The duration of the long tap in ms.
+	 */
+	void gestureLongTapEvent(int x, int y, float duration);
+
+	/**
+	 * Gesture callback on Gesture::DRAG events.
+	 *
+	 * @param x The x-coordinate of the start of the drag event.
+	 * @param y The y-coordinate of the start of the drag event.
+	 */
+	void gestureDragEvent(int x, int y);
+
+	/**
+	 * Gesture callback on Gesture::DROP events.
+	 *
+	 * @param x The x-coordinate of the drop event.
+	 * @param y The y-coordinate of the drop event.
+	 */
+	void gestureDropEvent(int x, int y);
+
     /**
      * Script gamepad callback on gamepad events.
      *