2013-03-18 44 views
0

我需要帮助。我为黑莓手机制作游戏,但我在多点触控事件处理方面遇到了问题。我使用CInput类从例子中处理触摸事件,它的工作(所有触摸都有权利和触摸计数),但当同时使2触摸和释放触摸CInput不释放1事件和所有出错像我不释放触摸。我可以在模拟器或者手册中看到这个错误。这部分代码适用于touch。我该如何解决它?谢谢,如果有人可以帮助。遗憾的英语不好Marmalade SDK多点触控

void touchUpdate() 
{ 
    g_Input.Update(); 
    printf("count %d\n", g_Input.getTouchCount()); 
    if (g_Input.getTouchCount() != 0) 
    { 
     CTouch* touch; 
     if (g_Input.isMultiTouch()) 
     { 
      for (int i = 0; i < g_Input.getTouchCount(); i++) 
      { 
       touch = g_Input.getTouch(i); 
       if (touch != NULL) 
       { 
        if (!touch->active) 
        { 
         touch->x = -1; 
         touch->y = -1; 
         continue; 
        } 
        else if (checkButton(&btnAction, touch)) 
        { 
         if (menu->isGameEnabled()) 
         { 
          currentGame->eventAction(); 
         } 
         else 
         { 
          currentGame = menu->eventAction(); 
         } 
         continue; 
        } 
        else if (checkButton(&btnUp, touch)) 
        { 
         if (menu->isGameEnabled()) 
         { 
          currentGame->eventUp(); 
         } 
         else 
         { 
          menu->eventUp(); 
         } 
         continue; 
        } 
        else if (checkButton(&btnDown, touch)) 
        { 
         if (menu->isGameEnabled()) 
         { 
          currentGame->eventDown(); 
         } 
         else 
         { 
          menu->eventDown(); 
         } 
         continue; 
        } 
        else if (checkButton(&btnLeft, touch)) 
        { 
         if (menu->isGameEnabled()) 
         { 
          currentGame->eventLeft(); 
         } 
         else 
         { 
          menu->eventLeft(); 
         } 
         continue; 
        } 
        else if (checkButton(&btnRight, touch)) 
        { 
         if (menu->isGameEnabled()) 
         { 
          currentGame->eventRight(); 
         } 
         else 
         { 
          menu->eventRight(); 
         } 
         continue; 
        } 
        else if (checkButton(&btnPause, touch)) 
        { 
         if (menu->isGameEnabled()) 
         { 
          currentGame->eventPause(); 
         } 
         continue; 
        } 
        else if (checkButton(&btnSound, touch)) 
        { 
         // off/on sound 
         continue; 
        } 
        else if (checkButton(&btnMenu, touch)) 
        { 
         // force drop to menu 
         if (menu->isGameEnabled()) 
         { 
          currentGame->eventMenu(); 
         } 
         continue; 
        } 
       } 
      } 
     } 
    } 
} 

currentGame-> eventMenu(),currentGame-> eventUp(),等等......它只是在游戏逻辑或主菜单功能。这个功能必须在按下按钮时总是调用。

struct roundButton 
{ 
    int x, y; 
    int radius; 
    bool pressed; 
}; 

bool checkButton(roundButton *button, CTouch *touch) 
{ 
    if ((button->x - touch->x) * (button->x - touch->x) + (button->y - touch->y) * (button->y - touch->y) <= button->radius * button->radius) 
    { 
     button->pressed = true; 
     return true; 
    } 
    return false; 
} 

这是我检查我的按钮按下或不

#ifndef SRC_INPUT_H_ 
#define SRC_INPUT_H_ 

#include "IwGeom.h" 
#include "s3ePointer.h" 

#define MAX_TOUCHES 2 

struct CTouch 
{ 
public: 
    int x, y; 
    bool active; 
    int id; 
}; 

class CInput 
{ 
private: 
    bool  Available;           // true if a pointer is present 
    bool  IsMultiTouch;          // true if multitouch is enabled 
    CTouch  Touches[MAX_TOUCHES];        // List of potential touches 
public: 
    bool  isAvailable() const { return Available; }   // Returns availability of the pointer 
    bool  isMultiTouch() const { return IsMultiTouch; }  // Returns multitouch capability 
    CTouch*  getTouchByID(int id);        // returns the touch identified by its id 
    CTouch*  getTouch(int index) { return &Touches[index]; }  // Gets a specific touch 
    CTouch*  findTouch(int id);         // Finds a specific touch by its id 
    int   getTouchCount() const;        // Get number of touches this frame 
public: 
    bool  Init();            // Initialises the input system (returns true if pointer is supported) 
    void  Release();           // Releases data used by the input system 
    void  Update();           // Updates the input system, called every frame 
}; 

extern CInput g_Input; 

#endif // SRC_INPUT_H_ 

CInput类

#include "input.h" 

CInput g_Input; 

void HandleMultiTouchButtonCB(s3ePointerTouchEvent* event) 
{ 
    CTouch* touch = g_Input.findTouch(event->m_TouchID); 
    if (touch != NULL) 
    { 
     touch->active = event->m_Pressed != 0; 
     touch->x = event->m_x; 
     touch->y = event->m_y; 
    } 
} 

void HandleMultiTouchMotionCB(s3ePointerTouchMotionEvent* event) 
{ 
    CTouch* touch = g_Input.findTouch(event->m_TouchID); 
    if (touch != NULL) 
    { 
     touch->x = event->m_x; 
     touch->y = event->m_y; 
    } 
} 

void HandleSingleTouchButtonCB(s3ePointerEvent* event) 
{ 
    CTouch* touch = g_Input.getTouch(0); 
    touch->active = event->m_Pressed != 0; 
    touch->x = event->m_x; 
    touch->y = event->m_y; 
} 

void HandleSingleTouchMotionCB(s3ePointerMotionEvent* event) 
{ 
    CTouch* touch = g_Input.getTouch(0); 
    touch->x = event->m_x; 
    touch->y = event->m_y; 
} 

CTouch* CInput::findTouch(int id) 
{ 
    if (!Available) 
     return NULL; 

    for (int t = 0; t < MAX_TOUCHES; t++) 
    { 
     if (Touches[t].id == id) 
      return &Touches[t]; 
     if (!Touches[t].active) 
     { 
      Touches[t].id = id; 
      return &Touches[t]; 
     } 
    } 

    return NULL; 
} 

CTouch* CInput::getTouchByID(int id) 
{ 
    for (int t = 0; t < MAX_TOUCHES; t++) 
    { 
     if (Touches[t].active && Touches[t].id == id) 
      return &Touches[t]; 
    } 

    return NULL; 
} 

int CInput::getTouchCount() const 
{ 
    if (!Available) 
     return 0; 

    int count = 0; 
    for (int t = 0; t < MAX_TOUCHES; t++) 
    { 
     if (Touches[t].active) 
      count++; 
    } 

    return count; 
} 

bool CInput::Init() 
{ 
    Available = s3ePointerGetInt(S3E_POINTER_AVAILABLE) ? true : false; 
    if (!Available) 
     return false; 

    for (int t = 0; t < MAX_TOUCHES; t++) 
    { 
     Touches[t].active = false; 
     Touches[t].id = 0; 
    } 
    IsMultiTouch = s3ePointerGetInt(S3E_POINTER_MULTI_TOUCH_AVAILABLE) ? true : false; 
    if (IsMultiTouch) 
    { 
     s3ePointerRegister(S3E_POINTER_TOUCH_EVENT, (s3eCallback)HandleMultiTouchButtonCB, NULL); 
     s3ePointerRegister(S3E_POINTER_TOUCH_MOTION_EVENT, (s3eCallback)HandleMultiTouchMotionCB, NULL); 
    } 
    else 
    { 
     s3ePointerRegister(S3E_POINTER_BUTTON_EVENT, (s3eCallback)HandleSingleTouchButtonCB, NULL); 
     s3ePointerRegister(S3E_POINTER_MOTION_EVENT, (s3eCallback)HandleSingleTouchMotionCB, NULL); 
    } 
    return true; 
} 

void CInput::Release() 
{ 
    if (Available) 
    { 
     if (IsMultiTouch) 
     { 
      s3ePointerUnRegister(S3E_POINTER_TOUCH_EVENT, (s3eCallback)HandleMultiTouchButtonCB); 
      s3ePointerUnRegister(S3E_POINTER_TOUCH_MOTION_EVENT, (s3eCallback)HandleMultiTouchMotionCB); 
     } 
     else 
     { 
      s3ePointerUnRegister(S3E_POINTER_BUTTON_EVENT, (s3eCallback)HandleSingleTouchButtonCB); 
      s3ePointerUnRegister(S3E_POINTER_MOTION_EVENT, (s3eCallback)HandleSingleTouchMotionCB); 
     } 
    } 
} 

void CInput::Update() 
{ 
    if (Available) 
     s3ePointerUpdate(); 
} 
+0

我不认为这是一个剧本bug。我已经在使用橘子酱的剧本中使用了多点触控。尝试检查任何其他设备(可能是Android)。 – noob 2013-03-19 15:29:14

+0

即使在模拟器中也会发生这种情况。只是更难重现此错误 – art65536 2013-03-19 16:50:31

+0

这意味着代码存在一些问题。让我看看。 – noob 2013-03-19 18:16:36

回答

0

我找到的bug。函数findTouch可以返回甚至不主动的触摸。所以修复看起来像

CTouch* CInput::findTouch(int id) 
{ 
    if (!Available) 
     return NULL; 

    for (int t = 0; t < MAX_TOUCHES; t++) 
    { 
     if (Touches[t].id == id) 
     return &Touches[t]; 
    } 
    for (int t = 0; t < MAX_TOUCHES; t++) 
    { 
     if (!Touches[t].active) 
     { 
      Touches[t].id = id; 
      return &Touches[t]; 
     } 
    } 

    return NULL; 
}