Cocos2dx 对android支持原理

本文详细解析了Cocos2dx基于OpenGL ES在Android平台上的运行机制。从MainActivity入口开始,介绍如何加载libgame.so,接着阐述Cocos2dxActivity的onCreate()方法中的核心逻辑,包括创建GLSurfaceView,设置渲染器并调用Cocos2dx的初始化函数。文章还讨论了AndroidManifest.xml中声明的GL ES版本需求,以及在activity状态变化时如何调用相应的方法。此外,文章探讨了UI线程和渲染线程如何协同工作,实现游戏画面的更新与用户交互。最后,指出接入SDK时需注意线程同步问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Cocos2dx 基于opengl es 实现跨平台功能,虽然android 已经支持native ,还是需要使用到android平台中的特性。

首先从程序的主入口 MainActivity MainActivity跟进java首先加载static函数,将libgame.so导入进来,

根据activity的生命周期,首先调用oncreate()方法,由于继承Cocos2dxActivity类将调用该类的oncreate(),Cocos2dxActivity的核心Init()函数如下:

public void init()

{

ViewGroup.LayoutParams framelayout_params = new   ViewGroup.LayoutParams(

ViewGroup.LayoutParams.FILL_PARENT,

ViewGroup.LayoutParams.FILL_PARENT);

FrameLayout framelayout = new FrameLayout(this);

framelayout.setLayoutParams(framelayout_params);

ViewGroup.LayoutParams edittext_layout_params = new ViewGroup.LayoutParams(

ViewGroup.LayoutParams.FILL_PARENT,

ViewGroup.LayoutParams.WRAP_CONTENT);

Cocos2dxEditText edittext = new Cocos2dxEditText(this);

edittext.setLayoutParams(edittext_layout_params);

framelayout.addView(edittext);

this.mGLSurfaceView = this.onCreateView();

        this.mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 0, 8);

framelayout.addView(this.mGLSurfaceView);

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

this.mGLSurfaceView.setCocos2dxEditText(edittext);

mFrameLayout = framelayout;

}

 创建一个framelayout 将mGLSurfaceView add进来,并且mGLSurfaceView 通过setCocos2dxRenderer设置一个cocos2dxRenderer,并通过GLThread调起RendereronSurfaceCreated方法(android sdk GLSurfaceView.java)cocos2dx的引擎也就初始化完成。

@Override

public void onSurfaceCreated(final GL10 pGL10, final EGLConfig pEGLConfig) 

{

Cocos2dxRenderer.nativeInit(this.mScreenWidth, this.mScreenHeight);

this.mLastTickInNanoSeconds = System.nanoTime();

}

nativeInit使用jni的形式调起c++函数

void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv*  env, jobject thiz, jint w, jint h)

{

    if (!CCDirector::sharedDirector()->getOpenGLView())

    {

        CCEGLView *view = CCEGLView::sharedOpenGLView();

        view->setFrameSize(w, h);

        AppDelegate *pAppDelegate = new AppDelegate();

        CCApplication::sharedApplication()->run();

}

}

android平台上,cocos2dx游戏入口跑起来了,依照android平台的特性需要使用opengl es需要在AndroidMainfest.xml中声明

<uses-feature android:glEsVersion="0x00020000" android:required="true" />

2、onstart ,没有对其进行重写,调用基类 Activity 方法,不分析。

3、onResume(),基类 Cocos2dxGLSurfaceView

@Override

public void onResume() {

super.onResume();

 

this.queueEvent(new Runnable() {

@Override

public void run() {Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleOnResume();

}

});

}

     public void handleOnResume() {

Cocos2dxRenderer.nativeOnResume();

}

 JNIEXPORT void JNICALLJava_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnResume() {

        if (CCDirector::sharedDirector()->getOpenGLView()) {

       CCApplication::sharedApplication()->applicationWillEnterForeground();

        }

}

当active的重新需要显示的时,java的activity跟.so中的c++中的函数关联起来,同理之后的onResume()也是这样跟c++中的关联起来。只需要在对应的c++函数中填写逻辑。

4、游戏 是由 画面构建而成,让画面动起来就需要重绘、渲染,借助GLSurfaceView.Renderer渲染。

    @Override

public void onDrawFrame(final GL10 gl) 

{

Cocos2dxRenderer.nativeRender();

mFrameCount += 1;

if (mFrameCount % 100 == 0)

{

Cocos2dxHelper.checkMemoryWarning();

}

}

JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeRender(JNIEnv* env) {

        cocos2d::CCDirector::sharedDirector()->mainLoop();

}


将调用c++中的CCDirector的mainLoop,游戏的循环已经被调用起来,在游戏的mainloop将会实现游戏的检测、绘制等任务。


5、android 如何驱动Renderer的onDrawFrame()

 由GLSurfaceView在setCocos2dxRenderer调用GLThread线程,GLThread线程中

    if (LOG_RENDERER_DRAW_FRAME) {

      Log.w("GLThread", "onDrawFrame tid=" + getId());

     }

    {

     GLSurfaceView view = mGLSurfaceViewWeakRef.get();

     if (view != null) {

          view.mRenderer.onDrawFrame(gl);

      }

    }

GLThread 外部就是一个while(true),不停的驱动渲染画面,让游戏动起来。


6、Ui Thread 跟 GLThread

  手游引擎需要兼顾UI事件跟屏幕帧数的刷新,在andorid中采用了UI线程+渲染线程,UI线程捕获跟用户交互的信息和事件,并跟渲染进程交互对游戏进行渲染,例如上述的setCocos2dxRenderer设置了渲染进程。

  在接入SDK的登录的时候需要将Login 函数写入 runGLthread 中。

@Override

public void runOnGLThread(final Runnable pRunnable)

{

this.mGLSurfaceView.queueEvent(pRunnable);

}

    public void queueEvent(Runnable r) {

            if (r == null) {

                throw new IllegalArgumentException("r must not be null");

            }

            synchronized(sGLThreadManager) {

                mEventQueue.add(r);

                sGLThreadManager.notifyAll();

            }

        }

GLThread run中:

 if (! mEventQueue.isEmpty()) {

      event = mEventQueue.remove(0);

      break;

 }

if (event != null) {

                        event.run();

                        event = null;

                        continue;

            }


当点击登录,UI线程捕获到了,需要传递给引擎,让渲染线程根据画面的元素的状态重新绘画,UI线程通过this.mGLSurfaceView.queueEvent(pRunnable);将事件以及处理方法传递给GLThread来执行,完成了UI线程跟GLThread之间的通讯。

在android系统中通过UI线程,如果不在这两个方式中改变UI组件的属性,那么有SDK

一些图像显示过程将显示不来了。

有时候我们需要将SDK的接口放置在UI线程中,因为SDK 接口可能需要改变到UI组件的属性。

 

Cocos2dx 本身依靠opengl es 完成跨平台,在android平台下面android已有的opengl es API实现对android平台的支持.所以能够看到主要还是继承的COcos2dxActivity 来完成 对cocos2dx 引擎中的 API进行控制,达到控制游戏的目的。

在cocos2dx android目录下还能够看到很多*.java文件,例如音乐 cocos2dx本身通过调用android的API来调用android的硬件资源来实现功能。

 

参考文件:cocos2d-x-2.2.5\cocos2dx\platform\android

http://code.taobao.org/p/cnandroiddocs/src/trunk/opengl/java/android/opengl/GLSurfaceView.java

参考网站:

http://www.cnblogs.com/helloandroid/articles/2948081.html

http://blog.sina.com.cn/s/blog_69887cd70100jxmu.html

http://my.oschina.net/bankofchina/blog/284150

http://www.jb51.net/article/49452.htm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值