Мармелад SDK Мультитач

Мне нужна помощь. Я делаю игру для BlackBerry Playbook, но у меня проблемы с обработкой событий мультитач. Я использую класс CInput, взятый из примеров, для обработки событий касания, он работает (все касания имеют правильные координаты и счетчик касаний тоже правильно), но когда происходит одновременное касание 2 и отпускание касания, CInput не выпускает события 1 и все идет не так, как я не отпускаю трогают. Я могу увидеть эту ошибку в симуляторе или на Playbook. эта часть кода для работы с сенсорным. Как я могу это исправить? спасибо, если кто-то может помочь. Извините за плохой английский

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

Решение

Я нахожу ошибку. Функция 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;
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]