展会信息港展会大全

Cocos2dx引擎8-事件处理
来源:互联网   发布日期:2015-09-27 15:32:29   浏览:2261次  

导读: 本文从主要介绍点击事件的处理过程,分别从win32、Android、IOS系统介绍Cocos2dx点击事件处理过程。 1、Win32系统 AppDelegate::applicatio...

本文从主要介绍点击事件的处理过程,分别从win32、Android、IOS系统介绍Cocos2dx点击事件处理过程。

1、Win32系统

AppDelegate::applicationDidFinishLaunching()->GLView::create(…)->GLView::initWithRect(…)

bool GLView::initWithRect(conststd::string& viewName, Rect rect, float frameZoomFactor){

………

glfwSetMouseButtonCallback(_mainWindow,

GLFWEventHandler::onGLFWMouseCallBack);

………

}

在win32系统中点击事件为鼠标点击事件,使用glfwSetMouseButtonCallback绑定鼠标点击事件的时间处理函数;

static voidonGLFWMouseCallBack(GLFWwindow* window, int button, int action, int modify){

if (_view) _view->onGLFWMouseCallBack(window,button, action, modify);

}

voidGLView::onGLFWMouseCallBack(GLFWwindow* window, int button, int action, intmodify){

if(GLFW_MOUSE_BUTTON_LEFT == button) {//鼠标左键时

if(GLFW_PRESS == action) {//鼠标左键按下时

_captured = true;

if(this->getViewPortRect().equals(Rect::ZERO) ||

this->getViewPortRect().containsPoint(Vec2(_mouseX,_mouseY))){

intptr_t id = 0;

this->handleTouchesBegin(1, &id, &_mouseX, &_mouseY);

}

}elseif(GLFW_RELEASE == action) {//鼠标左键松开时

if(_captured) {

_captured = false;

intptr_t id = 0;

this->handleTouchesEnd(1, &id, &_mouseX, &_mouseY);

}

}

}

………//处理鼠标事件

}

上面的处理方法代码位于cocos2d\cocos\platform\win32\ CCGLView.cpp中;

2、Android系统

public class Cocos2dxGLSurfaceView extends GLSurfaceView {

……

public booleanonTouchEvent(final MotionEvent pMotionEvent) {

……….

switch(pMotionEvent.getAction() & MotionEvent.ACTION_MASK) {

……

caseMotionEvent.ACTION_DOWN://按下事件

this.queueEvent(newRunnable() {//新起一个线程处理该事件

publicvoid run() {

Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionDown

(idDown, xDown,yDown);

}

});

break;

…………….

caseMotionEvent.ACTION_UP: //抬起事件

this.queueEvent(newRunnable() {

publicvoid run() {

Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionUp

(idUp, xUp, yUp);

}

});

break;

…………

}

return true;

}

}

Cocos2dxGLSurfaceView继承View类,实现View中关于触摸屏事件处理函数onTouchEvent,当有触摸屏事件发生时会调用Cocos2dxGLSurfaceView中onTouchEvent方法,在onTouchEvent方法中会区分Down&Up事件,并使用新的线程执行Cocos2dxRenderer类中handleActionDown&handleActionUp方法;

public class Cocos2dxRenderer implements GLSurfaceView.Renderer{

private static native void nativeTouchesBegin(final int pID, final float pX, final float pY);

private static native void nativeTouchesEnd(final int pID, final float pX, final float pY);

public void handleActionDown(finalint pID, final float pX, final float pY) {

Cocos2dxRenderer.nativeTouchesBegin(pID,pX, pY);

}

public voidhandleActionUp(final int pID, final float pX, final float pY) {

Cocos2dxRenderer.nativeTouchesEnd(pID,pX, pY);

}

}

在Cocos2dxRenderer类中的handleActionDown&handleActionUp方法会通过JNI调用C++实现的nativeTouchesBegin&nativeTouchesEnd方法;

nativeTouchesBegin&nativeTouchesEnd分别对应

cocos2d\cocos\platform\android\jni\TouchesJni.cpp文件中:

JNIEXPORT voidJNICALL

Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeTouchesBegin(JNIEnv * env, jobject thiz, jint id, jfloatx, jfloat y) {

cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesBegin(1,&id, &x, &y);

}

JNIEXPORT voidJNICALL

Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeTouchesEnd(JNIEnv * env, jobject thiz, jint id, jfloatx, jfloat y) {

cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesEnd(1,&id, &x, &y);

}

3、IOS系统

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

……

glview->handleTouchesBegin(i,(intptr_t*)ids, xs, ys);

}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

{

……

glview->handleTouchesEnd(i,(intptr_t*)ids, xs, ys);

}

以上方法在cocos2d\cocos\platform\ios\CCEAGLView.mm中实现;

4、Cocs2dx事件处理

上文中handleTouchesBegin和handleTouchesEnd处理在Win32、Android、IOS中是相同的实现,接下来会继续分析;

voidGLViewProtocol::handleTouchesBegin(int num, intptr_t ids[], float xs[], floatys[]){//点击按下时执行

intptr_t id = 0;

float x = 0.0f;

float y = 0.0f;

int unusedIndex = 0;

EventTouch touchEvent;

for (int i = 0; i setTouchInfo(unusedIndex,(x - _viewPortRect.origin.x) / _scaleX,

(y -_viewPortRect.origin.y) / _scaleY);

CCLOGINFO("x = %f y =%f", touch->getLocationInView().x, touch->getLocationInView().y);

//将当前Touch添加入Touch查询字典中

g_touchIdReorderMap.insert(std::make_pair(id, unusedIndex));

touchEvent._touches.push_back(touch);

}

}

……

touchEvent._eventCode =EventTouch::EventCode::BEGAN;

auto dispatcher =Director::getInstance()->getEventDispatcher();

dispatcher->dispatchEvent(&touchEvent);//分发Touch事件

}

在handleTouchesBegin中:

(1)查询点击是否已经存在

(2)若点击记录中不存在当前点击,则收集点击信息,分发TouchBegin事件

在过程(1)中单点点击中传入的ids={0},点击事件是存储在touchIdReorderMap[0]位置,这么做事防止出现点击同一个位置时未释放前,出现点击其他位置从而调用handleTouchesBegin;

voidGLViewProtocol::handleTouchesEnd(int num, intptr_t ids[], float xs[], floatys[]){ //点击释放时执行

handleTouchesOfEndOrCancel(EventTouch::EventCode::ENDED, num, ids, xs,ys);

}

void GLViewProtocol::handleTouchesOfEndOrCancel(EventTouch::EventCodeeventCode, int num, intptr_t ids[], float xs[], float ys[])

{

intptr_t id = 0;

float x = 0.0f;

float y = 0.0f;

EventTouch touchEvent;

for (int i = 0; i second];

if (touch) {

touch->setTouchInfo(iter->second,(x - _viewPortRect.origin.x) / _scaleX,

(y -_viewPortRect.origin.y) / _scaleY);

touchEvent._touches.push_back(touch);

g_touches[iter->second] =nullptr;

removeUsedIndexBit(iter->second);

g_touchIdReorderMap.erase(id);//移除已经释放点击事件

}

……

}

……

touchEvent._eventCode = eventCode;

auto dispatcher =Director::getInstance()->getEventDispatcher();

dispatcher->dispatchEvent(&touchEvent);//派发点击释放事件

for(auto& touch : touchEvent._touches) {//释放点击

touch->release();

}

}

在handleTouchesOfEndOrCancel中:

(1)查询点击是否已经存在

(2)若点击记录存在点击,则收集点击信息,分发TouchEnd事件

因为在单点点击中传入的ids={0},只有查询到该点击事件存在才会执行释放操作,最后会将点击事件从g_touchIdReorderMap移除,保证在调用ToucheEnd之前一定有TouchBegin。

赞助本站

人工智能实验室
AiLab云推荐
推荐内容
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港