看来得好好研究下touch事件,非常重要的一个东东,因为智能手机经常要发生touch交互。
我们看下cocos2d-x里面是如何实现touch事件的注册和分发的:
首先看这个函数:
GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun cbfun);
是opengl的API:
但它是如何被调到的呢:
首先是
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // create the application instance AppDelegate app; EGLView eglView; eglView.init("TestCPP",400,800); return Application::getInstance()->run();//这里注意run }
int Application::run() { PVRFrameEnableControlWindow(false); // Main message loop: LARGE_INTEGER nFreq; LARGE_INTEGER nLast; LARGE_INTEGER nNow; QueryPerformanceFrequency(&nFreq); QueryPerformanceCounter(&nLast); // Initialize instance and cocos2d. if (!applicationDidFinishLaunching()) { return 0; } EGLView* pMainWnd = EGLView::getInstance();//新建一个EGLView类
bool EGLView::init(const char* viewName, float width, float height, float frameZoomFactor) { if(nullptr != _mainWindow) return true; setViewName(viewName); setFrameSize(width, height); setFrameZoomFactor(frameZoomFactor); glfwWindowHint(GLFW_RESIZABLE,GL_FALSE); _mainWindow = glfwCreateWindow(_screenSize.width * _frameZoomFactor, _screenSize.height * _frameZoomFactor, _viewName, nullptr, nullptr); glfwMakeContextCurrent(_mainWindow); glfwGetFramebufferSize(_mainWindow, &_frameBufferSize[0], &_frameBufferSize[1]); glfwSetMouseButtonCallback(_mainWindow,EGLViewEventHandler::OnGLFWMouseCallBack);//注意这里 glfwSetCursorPosCallback(_mainWindow,EGLViewEventHandler::OnGLFWMouseMoveCallBack); glfwSetCharCallback(_mainWindow, EGLViewEventHandler::OnGLFWCharCallback); glfwSetKeyCallback(_mainWindow, EGLViewEventHandler::OnGLFWKeyCallback);
void EGLViewEventHandler::OnGLFWMouseCallBack(GLFWwindow* window, int button, int action, int modify) { EGLView* eglView = EGLView::getInstance(); if(nullptr == eglView) return; if(GLFW_MOUSE_BUTTON_LEFT == button) { if(GLFW_PRESS == action) { s_captured = true; if (eglView->getViewPortRect().equals(Rect::ZERO) || eglView->getViewPortRect().containsPoint(Point(s_mouseX,s_mouseY))) { int id = 0; eglView->handleTouchesBegin(1, &id, &s_mouseX, &s_mouseY);//注意 } } else if(GLFW_RELEASE == action) { s_captured = false; if (eglView->getViewPortRect().equals(Rect::ZERO) || eglView->getViewPortRect().containsPoint(Point(s_mouseX,s_mouseY))) { int id = 0; eglView->handleTouchesEnd(1, &id, &s_mouseX, &s_mouseY); } } } }
void EGLViewProtocol::handleTouchesBegin(int num, int ids[], float xs[], float ys[]) { int id = 0; float x = 0.0f; float y = 0.0f; int nUnusedIndex = 0; EventTouch touchEvent; for (int i = 0; i < num; ++i) { id = ids[i]; x = xs[i]; y = ys[i]; auto iter = g_touchIdReorderMap.find(id); nUnusedIndex = 0; // it is a new touch if (iter == g_touchIdReorderMap.end()) { nUnusedIndex = getUnUsedIndex(); // The touches is more than MAX_TOUCHES ? if (nUnusedIndex == -1) { CCLOG("The touches is more than MAX_TOUCHES, nUnusedIndex = %d", nUnusedIndex); continue; } Touch* touch = g_touches[nUnusedIndex] = new Touch(); touch->setTouchInfo(nUnusedIndex, (x - _viewPortRect.origin.x) / _scaleX, (y - _viewPortRect.origin.y) / _scaleY); CCLOGINFO("x = %f y = %f", pTouch->getLocationInView().x, pTouch->getLocationInView().y); g_touchIdReorderMap.insert(std::make_pair(id, nUnusedIndex)); touchEvent._touches.push_back(touch); } } if (touchEvent._touches.size() == 0) { CCLOG("touchesBegan: size = 0"); return; } touchEvent._eventCode = EventTouch::EventCode::BEGAN; EventDispatcher::getInstance()->dispatchEvent(&touchEvent);//在这里会分发并回调touch的相关事件和回调函数 }ok,想要了解细节,还是看源码吧,很清晰。因为木有设置啥多线程调用。