• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

chchpd

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

cocos2dx --- Touch (二)

  本文是关于cocos2dx获取并进行处理Android的滑屏事件,实现一个动态壁纸的效果。关于Android的本身的滑屏处理不在本文范围内。

  在Android层面需要继承XXXWallPaperService,并实现onOffesetsChanged方法,当然为了使得cocos2dx获取onOffsetsChaneged事件,需要额外定义JNI接口,通过JNI接口,实现Cocos2dx的动态滑屏效果。

   实现:

  1).JNI接口(Java,C++)

 1 public class ClassName implements GLWallpaperService.Renderer {
 2     private boolean isCreate = false;
 3     public VRenderer mRenderer;
 4     public ClassName(int width,int height){
 5         mRenderer = new VRenderer();
 6         mRenderer.setScreenWidthAndHeight(width, height);
 7     }
 8     public void handleActionDown(final int pID, final float pX, final float pY) {
 9         if(mRenderer!=null){
10             mRenderer.handleActionDown(pID, pX, pY);
11         }
12     }
13     public void handleActionMove(final int[] pIDs, final float[] pXs, final float[] pYs) {
14         if(mRenderer!=null){
15             mRenderer.handleActionMove(pIDs, pXs, pYs);
16         }
17     }
18     public void handleActionUp(final int pID, final float pX, final float pY) {
19         if(mRenderer!=null){
20             mRenderer.handleActionUp(pID, pX, pY);
21         }
22     }
23     public void handleActionCancel(final int[] pIDs, final float[] pXs, final float[] pYs) {
24         if(mRenderer!=null){
25             mRenderer.handleActionCancel(pIDs, pXs, pYs);
26         }
27     }
28     public void onDrawFrame(GL10 gl) {
29         VRenderer.nativeRender();
30     }
31     public void onSurfaceChanged(GL10 gl, int width, int height){
32         mRenderer.onSurfaceChanged(gl, width, height);
33     }
34     public void onSurfaceCreated(GL10 gl, EGLConfig config) {
35         if(!isCreate){
36             mRenderer.onSurfaceCreated(gl, config);
37             isCreate = true;
38         } else {
39             mRenderer.handleOnResume();
40         }
41         
42     }
43     public enum Status{
44         pause,resume;
45     }
46     public void onPause(){
47 //        mRenderer.nativeStatus(Status.pause);
48     }
49     public void onResume(){
50 //        mRenderer.nativeStatus(Status.resume);
51     }
52     /**
53      * Called when the engine is destroyed. Do any necessary clean up because
54      * at this point your renderer instance is now done for.
55      */
56     public void release() {
57     }
58     public void onOffsetsChanged(float xOffset, float yOffset,float xOffsetStep, float yOffsetStep, int xPixelOffset,int yPixelOffset) {
59         LoggerFactory.getLogger(getClass()).info("xOffset:{} yOffset:{} xStep:{} yStep:{} xOffset:{} yOffset:{}", new Object[]{xOffset, yOffset, xOffsetStep, yOffsetStep, xPixelOffset, yPixelOffset});
60         mRenderer.handleSlideScreen(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixelOffset, yPixelOffset);        
61     }
62 }
 1 #include "cocoa/CCSet.h"
 2 #include "CCDirector.h"
 3 #include "keypad_dispatcher/CCKeypadDispatcher.h"
 4 #include "touch_dispatcher/CCTouch.h"
 5 #include "../CCEGLView.h"
 6 #include "touch_dispatcher/CCTouchDispatcher.h"
 7 #include <android/log.h>
 8 #include <jni.h>
 9 
10 using namespace cocos2d;
11 
12 extern "C" {
13     void Java_packagename_classname_nativeTouchesBegin(JNIEnv * env, jobject thiz, jint id, jfloat x, jfloat y) {
14         cocos2d::CCDirector::sharedDirector()->getOpenGLView()->handleTouchesBegin(1, &id, &x, &y);
15     }
16     void Java_packagename_classname_nativeTouchesEnd(JNIEnv * env, jobject thiz, jint id, jfloat x, jfloat y) {
17         cocos2d::CCDirector::sharedDirector()->getOpenGLView()->handleTouchesEnd(1, &id, &x, &y);
18     }
19     void Java_packagename_classname_nativeTouchesMove(JNIEnv * env, jobject thiz, jintArray ids, jfloatArray xs, jfloatArray ys) {
20         int size = env->GetArrayLength(ids);
21         jint id[size];
22         jfloat x[size];
23         jfloat y[size];
24         env->GetIntArrayRegion(ids, 0, size, id);
25         env->GetFloatArrayRegion(xs, 0, size, x);
26         env->GetFloatArrayRegion(ys, 0, size, y);
27         cocos2d::CCDirector::sharedDirector()->getOpenGLView()->handleTouchesMove(size, id, x, y);
28     }
29     void Java_packagename_classname_nativeTouchesCancel(JNIEnv * env, jobject thiz, jintArray ids, jfloatArray xs, jfloatArray ys) {
30         int size = env->GetArrayLength(ids);
31         jint id[size];
32         jfloat x[size];
33         jfloat y[size];
34         env->GetIntArrayRegion(ids, 0, size, id);
35         env->GetFloatArrayRegion(xs, 0, size, x);
36         env->GetFloatArrayRegion(ys, 0, size, y);
37         cocos2d::CCDirector::sharedDirector()->getOpenGLView()->handleTouchesCancel(size, id, x, y);
38     }
39     void Java_packagename_classname_nativeSlideScreen(JNIEnv * env,jfloat offsetx,jfloat offsety,jfloat stepx,jfloat stepy,jfloat pixelx,jfloat pixely){
40         cocos2d::CCDirector::sharedDirector()->getOpenGLView()->handleSlideScreen(offsetx,offsety,stepx,stepy,pixelx,pixely);
41     }
42     #define KEYCODE_BACK 0x04
43     #define KEYCODE_MENU 0x52
44     jboolean Java_packagename_classname_nativeKeyDown(JNIEnv * env, jobject thiz, jint keyCode) {
45         CCDirector* pDirector = CCDirector::sharedDirector();
46         switch (keyCode) {
47             case KEYCODE_BACK:
48                   if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeBackClicked))
49                     return JNI_TRUE;
50                 break;
51             case KEYCODE_MENU:
52                 if (pDirector->getKeypadDispatcher()->dispatchKeypadMSG(kTypeMenuClicked))
53                     return JNI_TRUE;
54                 break;
55             default:
56                 return JNI_FALSE;
57         }
58         return JNI_FALSE;
59     }
60 }

  在上述代码中,主要关心的是SlideScreen相关的实现。

  2).cocos2dx中涉及触屏事件的类主要有:CCEGLView,CCEGLViewProtocal,EGLTouchDelegate,CCTouchDispatcher,CCTouchDelegate,CCTouch.其主要关系为,CCEGLView继承CCEGLViewProtocal,通过CCDirector的静态实例获取EGLView后,调用了CCEGLViewProtocal的handleSlideScreen方法。在handleSlideScreen方法中设置Touch事件的信息,并将事件委托给EGLTouchDelegate的slideScreenByTouches,EGLTouchDelegate同样是纯虚类,有CCTouchDispatcher继承并实现,这个过程主要用于确定事件类型和事件分发。在事件分发过程中将事件同样委托给CCTouchDelegate,由于CCTargetedTouchDelegate、CCStandardTouchDelegate继承了CCTouchDelegate,并且在CCTouchDispatcher过程中确定了事件类型,因此将调用响应的ccSlideScreenByTouches或ccSlideScreenByTouch。当然最终要何种效果,有用户继承ccSlideScreenByTouch(ccSlideScreenByTouches)实现。另外一点需要是,需要在CCTouch中实现对应的方法,以便设置和获取滑屏的信息。

  Java_packagename_classname_nativeSlideScreen中调用了handleSlideScreen(),因此需要在CCEGLViewProtocal定义并实现handleSlideScreen,具体如下:

 1     CCSet set;
 2     CCLog("CCEGLViewProtocol slide value (%f,%f,%f,%f,%f,%f)",offsetx,offsety,stepx,stepy,pixelx,pixely);
 3     uniq_Touch = new CCTouch();
 4     if (uniq_Touch){
 5         CCLog("CCEGLViewProtocol slide screen");
 6         uniq_Touch->setSlideScreenInfo(offsetx,offsety,stepx,stepy,pixelx,pixely);
 7         uniq_Touch->release();
 8       } else{
 9         CCLOG("CCEGLViewProtocol slide screen error");
10         return;
11       }
12     if (set.count() == 0){
13         CCLOG("CCEGLViewProtocol slide screen count = 0");
14         return;
15     }
16     m_pDelegate->sliedScreenByTouches(&set,NULL);

slideScreenByTouches在EGLTouchDelegate定义,EGLTouchDelegate是一个纯虚类,CCTouchDispatcher继承并实现了slideScreenByTouches,如下:

 1 void CCTouchDispatcher::sliedScreenByTouches(CCSet* touches, CCEvent* pEvent) {
 2     CCLog("CCTouchDispatcher::sliedScreenByTouches begin");
 3     if (m_bDispatchEvents) {
 4         CCLog("CCTouchDispatcher::sliedScreenByTouches init,CCSet contians %d",touches->count());
 5         CCSet *pMutableTouches;
 6         unsigned int uTargetedHandlersCount = m_pTargetedHandlers->count();
 7         unsigned int uStandardHandlersCount = m_pStandardHandlers->count();
 8         bool bNeedsMutableSet = (uTargetedHandlersCount&& uStandardHandlersCount);
 9         pMutableTouches =(bNeedsMutableSet ? touches->mutableCopy() : touches);
10         CCTouch *pTouch;
11         CCSetIterator setIter;
12         for (setIter = touches->begin(); setIter != touches->end();++setIter) {
13             pTouch = (CCTouch *) (*setIter);
14             CCLog("1---CCTouchDispatcher::sliedScreenByTouches");
15             CCTargetedTouchHandler *pHandler = NULL;
16             CCObject* pObj = NULL;
17             CCARRAY_FOREACH(m_pTargetedHandlers, pObj) {
18                 pHandler = (CCTargetedTouchHandler *) (pObj);
19                 if (!pHandler) {
20                     CCLog("2---CCTouchDispatcher::sliedScreenByTouches");
21                     break;
22                 } else{
23                     CCLog("3---CCTouchDispatcher::sliedScreenByTouches");
24                     pHandler->getDelegate()->ccSlideScreenByTouch(pTouch,pEvent);
25                     pHandler->getClaimedTouches()->removeObject(pTouch);
26                 }
27             }
28             CCLog("4---CCTouchDispatcher::sliedScreenByTouches");
29             if (pHandler->isSwallowsTouches()) {
30                 if (bNeedsMutableSet) {
31                     CCLog("5---CCTouchDispatcher::sliedScreenByTouches");
32                     pMutableTouches->removeObject(pTouch);
33                 }
34                 break;
35             }
36         }
37         if (uStandardHandlersCount > 0 && pMutableTouches->count() > 0) {
38             CCLog("6---CCTouchDispatcher::sliedScreenByTouches");
39             CCStandardTouchHandler *pHandler = NULL;
40             CCObject* pObj = NULL;
41             CCARRAY_FOREACH(m_pStandardHandlers, pObj) {
42                 pHandler = (CCStandardTouchHandler*) (pObj);
43                 if (!pHandler) {
44                     CCLog("7---CCTouchDispatcher::sliedScreenByTouches");
45                     break;
46                 }
47                 CCLog("8---CCTouchDispatcher::sliedScreenByTouches");
48                 pHandler->getDelegate()->ccSlideScreenByTouches(pMutableTouches,
49                         pEvent);
50             }
51         }
52         CCLog("CCTouchDispatcher::sliedScreenByTouches end");
53     }
54 }

通过CCTouchDispatcher后,将滑屏交给了CCTouchHandler去处理,CCTouchHandler获取委托类型,并交给相应的委托类进行处理。因为从Android层将滑屏的参数传递给了cocos2dx,因此需要在CCTouch中实现对参数的处理。

1     void setSlideScreenInfo(float offsetx,float offsety,float stepx,float stepy,float pixelx,float pixely){
2         m_slideScreen.m_offsetX = offsetx;
3         m_slideScreen.m_offsetY = offsety;
4         m_slideScreen.m_stepX = stepx;
5         m_slideScreen.m_stepY = stepy;
6         m_slideScreen.m_pixelX = pixelx;
7         m_slideScreen.m_pixelY = pixely;
8     }
9     SlideScreen getSlideScreenInfo()const{return m_slideScreen;}

 

 

 

posted on 2013-05-15 13:59  chchpd  阅读(510)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3