cocos2dx android平台事件系统解析

对于cocos2dx在android平台事件的响应过程很模糊,于是分析了下源码,cocos2dx 版本3.4,先导入一个android工程,然后看下AndroidManifest.xml

    <application android:label="@string/app_name"
                 android:icon="@drawable/icon">

        <!-- Tell Cocos2dxActivity the name of our .so -->
        <meta-data android:name="android.app.lib_name"
                  android:value="cocos2dcpp" />

        <activity android:name="org.cocos2dx.cpp.AppActivity"
                  android:label="@string/app_name"
                  android:screenOrientation="landscape"
                  android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
                  android:configChanges="orientation">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

由此得知启动窗口类为 org.cocos2dx.cpp.AppActivity,并继承之 Cocos2dxActivity

package org.cocos2dx.cpp;

import org.cocos2dx.lib.Cocos2dxActivity;

public class AppActivity extends Cocos2dxActivity {
}
public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelperListener 

看下 Cocos2dxActivity 的 onCreate

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        Log.i(TAG, "------onCreate----");
        super.onCreate(savedInstanceState);
        CocosPlayClient.init(this, false);

        onLoadNativeLibraries();//加载了一些静态库

        sContext = this;
        this.mHandler = new Cocos2dxHandler(this);

        Cocos2dxHelper.init(this);

        this.mGLContextAttrs = getGLContextAttrs();
        this.init();//初始化

        if (mVideoHelper == null) {
            mVideoHelper = new Cocos2dxVideoHelper(this, mFrameLayout);
        }

        if(mWebViewHelper == null){
            mWebViewHelper = new Cocos2dxWebViewHelper(mFrameLayout);
        }
    }

onCreate 调用了  init()  初始化

   public void init() {

        // FrameLayout
        ViewGroup.LayoutParams framelayout_params =
            new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                                       ViewGroup.LayoutParams.MATCH_PARENT);
        mFrameLayout = new FrameLayout(this);
        mFrameLayout.setLayoutParams(framelayout_params);

        // Cocos2dxEditText layout
        ViewGroup.LayoutParams edittext_layout_params =
            new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                                       ViewGroup.LayoutParams.WRAP_CONTENT);
        Cocos2dxEditText edittext = new Cocos2dxEditText(this);
        edittext.setLayoutParams(edittext_layout_params);

        // ...add to FrameLayout
        mFrameLayout.addView(edittext);

        // Cocos2dxGLSurfaceView
        this.mGLSurfaceView = this.onCreateView();

        // ...add to FrameLayout
        mFrameLayout.addView(this.mGLSurfaceView);

        // Switch to supported OpenGL (ARGB888) mode on emulator
        if (isAndroidEmulator())
           this.mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);

        this.mGLSurfaceView.setCocos2dxRenderer(new Cocos2dxRenderer());
        this.mGLSurfaceView.setCocos2dxEditText(edittext);

        // Set framelayout as the content view
        setContentView(mFrameLayout);
    }

最终显示的视图为 this.mGLSurfaceView = this.onCreateView();

    public Cocos2dxGLSurfaceView onCreateView() {
        Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
        //this line is need on some device if we specify an alpha bits
        if(this.mGLContextAttrs[3] > 0) glSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);

        Cocos2dxEGLConfigChooser chooser = new Cocos2dxEGLConfigChooser(this.mGLContextAttrs);
        glSurfaceView.setEGLConfigChooser(chooser);

        return glSurfaceView;
    }

Cocos2dxGLSurfaceView 就是最终显示的视图,事件处理也在这个类中,包括 onResume,onPause,onSizeChanged,onKeyDown,onTouchEvent等 主要看下onTouchEvent事件的处理过程

 @Override
    public boolean onTouchEvent(final MotionEvent pMotionEvent) {

        //Log.d(TAG, "------onTouchEvent action=----"+pMotionEvent.getAction());

        // these data are used in ACTION_MOVE and ACTION_CANCEL
        final int pointerNumber = pMotionEvent.getPointerCount();
        final int[] ids = new int[pointerNumber];
        final float[] xs = new float[pointerNumber];
        final float[] ys = new float[pointerNumber];

        for (int i = 0; i < pointerNumber; i++) {
            ids[i] = pMotionEvent.getPointerId(i);
            xs[i] = pMotionEvent.getX(i);
            ys[i] = pMotionEvent.getY(i);
        }

        switch (pMotionEvent.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_POINTER_DOWN:
                final int indexPointerDown = pMotionEvent.getAction() >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
                final int idPointerDown = pMotionEvent.getPointerId(indexPointerDown);
                final float xPointerDown = pMotionEvent.getX(indexPointerDown);
                final float yPointerDown = pMotionEvent.getY(indexPointerDown);

                this.queueEvent(new Runnable() {
                    @Override
                    public void run() {
                        Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionDown(idPointerDown, xPointerDown, yPointerDown);
                    }
                });
                break;

            case MotionEvent.ACTION_DOWN:
                // there are only one finger on the screen
                final int idDown = pMotionEvent.getPointerId(0);
                final float xDown = xs[0];
                final float yDown = ys[0];

                this.queueEvent(new Runnable() {
                    @Override
                    public void run() {
                        Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionDown(idDown, xDown, yDown);
                    }
                });
                break;

            case MotionEvent.ACTION_MOVE:
                this.queueEvent(new Runnable() {
                    @Override
                    public void run() {
                        Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionMove(ids, xs, ys);
                    }
                });
                break;

            case MotionEvent.ACTION_POINTER_UP:
                final int indexPointUp = pMotionEvent.getAction() >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
                final int idPointerUp = pMotionEvent.getPointerId(indexPointUp);
                final float xPointerUp = pMotionEvent.getX(indexPointUp);
                final float yPointerUp = pMotionEvent.getY(indexPointUp);

                this.queueEvent(new Runnable() {
                    @Override
                    public void run() {
                        Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionUp(idPointerUp, xPointerUp, yPointerUp);
                    }
                });
                break;

            case MotionEvent.ACTION_UP:
                // there are only one finger on the screen
                final int idUp = pMotionEvent.getPointerId(0);
                final float xUp = xs[0];
                final float yUp = ys[0];

                this.queueEvent(new Runnable() {
                    @Override
                    public void run() {
                        Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionUp(idUp, xUp, yUp);
                    }
                });
                break;

            case MotionEvent.ACTION_CANCEL:
                this.queueEvent(new Runnable() {
                    @Override
                    public void run() {
                        Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionCancel(ids, xs, ys);
                    }
                });
                break;
        }

        /*
        if (BuildConfig.DEBUG) {
            Cocos2dxGLSurfaceView.dumpMotionEvent(pMotionEvent);
        }
        */
        return true;
    }

看下 MotionEvent.ACTION_DOWN,调用了Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleActionDown

    public void handleActionDown(final int id, final float x, final float y) {
        Log.i("Cocos2dxRenderer","-----handleActionDown--");
        Cocos2dxRenderer.nativeTouchesBegin(id, x, y);
    }

这里的nativeTouchesBegin 是一个jni方法,是现在cocos2d\cocos\platform\android\jni\TouchesJni.cpp里,

private static native void nativeTouchesBegin(final int id, final float x, final float y);
    JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeTouchesBegin(JNIEnv * env, jobject thiz, jint id, jfloat x, jfloat y) {
        intptr_t idlong = id;
        log("----Info:nativeTouchesBegin id = %d, x=%f, y=%f",id,x,y);
        cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesBegin(1, &idlong, &x, &y);
    }

最后调用GLView::handleTouchesBegin 通过 EventDispatcher::dispatchEvent进行事件的分发,调用事件响应函数,都是C++里完成的,就不再往下分析了。

能力有限,分析有误处请指正。

时间: 2024-12-08 04:11:43

cocos2dx android平台事件系统解析的相关文章

Android平台json解析(FastJson Gson 大比拼)

前言: 最近为了统一项目中使用的框架,发现项目中用到了两种json解析框架,他们就是当今非常主流的json解析框架:google的Gson 和阿里巴巴的FastJson,为了废除其中一个所以来个性能和使用的大比拼. FastJson 当前使用版本 fastjson-1.2.11.jar 下载地址http://repo1.maven.org/maven2/com/alibaba/fastjson/1.2.11/ 对象转化成json: /** * 对象转化为json fastjson 使用方式 *

Cocos2d-x 3.1.1 学习笔记(四)学习打包Android平台APK!

从cocos2dx 3.1项目打包成apk安卓应用文件,搭建安卓环境的步骤有点繁琐,但搭建一次之后,以后就会非常快捷! 一.下载Android环境 搭建Android环境需要用到Android SDK.NDK.Ant和JDK: Android SDK下载http://developer.android.com/sdk/index.html Android NDk下载http://developer.android.com/tools/sdk/ndk/index.html Android JDK下

Cocos2d-x 3.2 打包Android平台APK

(转自:http://www.cnblogs.com/Richard-Core/p/3855130.html) 从cocos2dx 3.2项目打包成apk安卓应用文件,搭建安卓环境的步骤有点繁琐,但搭建一次之后,以后就会非常快捷! (涉及到3.1.1版本的,请自动对应3.2版本,3.x版本的环境搭建都是一样的) 一.下载Android环境 搭建Android环境需要用到Android SDK.NDK.Ant和JDK: Android SDK下载http://developer.android.c

Cocos2d-x 3.0修改Android平台帧率fps - 解决游戏运行手机发热发烫问题

使用Cocos2d-x 3.0开发游戏之后,发现游戏在android手机上发热非常严重,在魅族2上,几乎担心手机会爆炸了~~~采取的一个措施就是降低帧率,因为游戏对于帧率要求不是非常高. 做过cocos2d开发的同学应该都知道在win32平台修改帧率的方式非常简单,就是在AppDelegate.cpp文件中修改: 1 director->setAnimationInterval(1.0 / 40); 但是这种修改方式在导出android安卓apk到真机测试的时候,发现左下角的调试信息还是现实60

Win7+VS2010+cocos2d-x 2.1 Beta3+Sqlite工程向android平台移植

Win7+VS2010+cocos2d-x 2.1 Beta3+Sqlite工程向android平台移植 题外话: 有时打开博客想写点什么时,心中感到有点酸楚,尽管语言不那么精简,或者说是准确,而且很可能文中的总结极不成熟,甚至还夹带些错误:但是,它们毕竟是自 己经过"痛苦"的挣扎后取得的一点成绩,于是,还是下决心记下来,一方面充实了自己尘封的笔记,另一方面也不敢独享-因为我看到有那么多的朋友把自己的心 血也无保留地奉献出来.或许,我的这一点一滴也能成为他们决战BUGS中的LITTLE

详解cocos2dx 3.0的release版本在android平台的签名过程

当您的游戏准备发布前,需要编译成为release版本,命令中需要增加 -m release,编译命令如下: cocos compile -p android -m release 在编译结束后,生成xxx_release_unsigned.apk,此时会提示进行签名,需要输入.keystore的路径. .keystore的生成方法: 使用keytool,命令如下: keytool -genkey -v -keystore my-release-key.keystore -alias alias_

Cocos2d-x移植到Android平台编译的两个文件Android.mk和Application.mk

背景 首先,说说文章的背景.最近手中的一个项目,由于需求中要求提供Web界面的打印功能,当然如果没有打印机,还可以提供保存到本地.项目组长把这个"小任务"分给了我.本着努力为组长分忧解难的思想,领了任务之后,就马上开始了工作. 问题 刚开始的时候,组长给了一个工具(jatoolsprinter)让我研究,我用了一个多小时的时间,做出了一个简单的Demo,然后就是各种的测试,由于 web 打印需要浏览器安装 ActiveX 组件,在随后的测试中,我用了几款浏览器,甚至把安全级别都调到了最

cocos2dx环境搭建(android平台)

http://blog.csdn.net/iamlazybone/article/details/16367965 cocos2dx环境搭建(android平台),布布扣,bubuko.com

cocos2dx项目移植android平台使用第三方so库被删掉的问题

cocos2dx项目android平台在编译的时候会把libs/armeabi目录清空,这就是为什么我们编译的时候导入的第三方so库会被删掉的原因. 解决方案: 1. 在jni目录下新建prebuilt目录,并把要使用的第三方so库复制到该目录: 2.修改jni/Android.mk文件如下: ok!搞定!