Cocos2d-x 3.3为Android平台提供的封装

前端之家收集整理的这篇文章主要介绍了Cocos2d-x 3.3为Android平台提供的封装前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

proj.android分析

AndroidManifest.xml

1. use opengl es 2.0

1
<uses-featureandroid:glEsVersion= "0x00020000" />

2. 问题1,在哪里用到的这个so?

1
2
3
<!--TellCocos2dxActivitythenameofour.so-->
<Meta-dataandroid:name= "android.app.lib_name"
android:value= "cpp_empty_test" 3. 支持的屏幕尺寸

3
4
5
<supports-screensandroid:anyDensity= "true"
android:smallScreens= "true"
android:normalScreens= "true"
android:largeScreens= "true"
android:xlargeScreens= "true"

assets目录

从Resources拷贝的资源

jni目录

除了make file外, 有个main.cpp, 内容如下:

5
6
7
8
9
10
11
12
13
14
//log相关
#defineLOG_TAG"main"
#defineLOGD(...)__android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
using namespace cocos2d;
//看起来怪怪的,new了一个AppDelegate之后,就不管了
//对比linux平台的,至少还调用了run方法
//问题2,谁调用的这个方法
void cocos_android_app_init(JNIEnv*env,jobjectthiz){
LOGD( "cocos_android_app_init" );
AppDelegate*pAppDelegate= new AppDelegate();
}

libs目录

由于我编译了,这个目录下有对应ABI的so。

src目录

AppActivity 代码如下

//看样子,料全在基类了
public class AppActivityextendsCocos2dxActivity{
小结下proj.android

留了两个问题待解答,详见下文。

Cocos2d-x针对Android平台的封装

cocos/platform/android/目录下都有什么

  • ControllerManualAdapter //粗略过了下代码,和游戏手柄相关,略

  • java代码

14
15
16
17
18
19
20
21
22
23
@H_819_301@ 24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//android加速度传感器事件对接。注册监听器后,android产生相应事件并
//回调到Cocos2dxAccelerometer的onSensorChanged再经过
//Cocos2dxGLSurfaceView.queueAccelerometer(x,y,z,sensorEvent.timestamp);
//之后调用到Cocos2dxAccelerometer的本地方法onSensorChanged
//该方法所在位置Java_org_cocos2dx_lib_Cocos2dxAccelerometer.cpp,
//该方法在native层dispatchEvent一个传感器事件
Cocos2dxAccelerometer.java
//java层的图片工具类,简单跟了下代码调用方向是从native方法调用到java层
Cocos2dxBitmap.java
//自定义了一个编辑对话框,对输入类型,键盘显示隐藏等做了些包装
Cocos2dxEditBoxDialog.java
//自定义编辑框,特殊处理了back按键
Cocos2dxEditText.java
//自定义handler,主要和弹出对话框相关
Cocos2dxHandler.java
//工具类,UserDefault存储相关的jni调用获取包名,终止进程等
//主要调用方向是native到java
Cocos2dxHelper.java
//数据库存储,主要供native端调用到java
Cocos2dxLocalStorage.java
//lua相关
Cocos2dxLuaJavaBridge.java
//java层的音乐播放相关,包装的MediaPlayer,用来播放长的音乐等
//主要由Cocos2dxHandler.java调用过来
//看样子音乐播放这块多半就是用的java层的播放器了
Cocos2dxMusic.java
//java层的音乐播放相关,包装的用soundpool,
//用来播一些短的反应速度要求高的音效
Cocos2dxSound.java
//输入事件监听相关,配合Cocos2dxGLSurfaceView的工作
Cocos2dxTextInputWraper.java
//Typefacecache相关
Cocos2dxTypefaces.java
//android视频播放器,MediaPlayer+SurfaceView
//对应的helper用来将videoview从父控件动态添加删除,简化调用
Cocos2dxVideoView.java
Cocos2dxVideoHelper.java
//自定义webview,类似上面的视频播放器的封装
Cocos2dxWebView.java
Cocos2dxWebViewHelper.java
//游戏手柄相关
GameControllerAdapter.java
GameControllerDelegate.java
GameControllerUtils.java
//放后面一起看TODO
Cocos2dxActivity.java
Cocos2dxRenderer.java
Cocos2dxGLSurfaceView.java
  • cpp

37
//application在android平台相关的实现,跨平台实现细节,针对平台的具体实现
CCApplication-android.cpp
CCApplication-android.h
//native层的工具类,通过jni调用到java层弹框等
CCCommon-android.cpp
//native层的工具类,获取dpi,设置加速监听器,图片处理等
CCDevice-android.cpp
//fileUtils的android平台相关的实现,类似application了
CCFileUtils-android.cpp
CCFileUtils-android.h
//一堆和opengl相关的宏等
CCGL-android.h
//glviewandroid平台的相关实现,类似application了
CCGLViewImpl-android.cpp
CCGLViewImpl-android.h
//一些宏定义
CCPlatformDefine-android.h
CCStdC-android.h
//放后面一起看TODO
javaactivity-android.cpp
//各种jni相关的helper类或者方法
//提一提touchesJni.cpp,他是用来对接androidtouch事件和key事件的
//和上面的加速器事件一样的逻辑,稍后看具体的事件源头
DPIJni.cpp
DPIJni.h
IMEJni.cpp
IMEJni.h
Java_org_cocos2dx_lib_Cocos2dxAccelerometer.cpp
Java_org_cocos2dx_lib_Cocos2dxBitmap.cpp
Java_org_cocos2dx_lib_Cocos2dxBitmap.h
Java_org_cocos2dx_lib_Cocos2dxHelper.cpp
Java_org_cocos2dx_lib_Cocos2dxHelper.h
Java_org_cocos2dx_lib_Cocos2dxRenderer.cpp
JniHelper.cpp
JniHelper.h
TouchesJni.cpp

上面一些非重点的代码java的C++的,我们都过了一遍,涉及的内容都和jni相关包括事件源头的对接,各种跨平台实现细节和输入弹框等。重点代码则是上面的几个标记为TODO的相关类, 接下来重点分析:

A. Cocos2dxActivity.java

48
49
50
51
52
53
54
55
56
57
58
59
60
1.oncreate
@Override
protected onCreate(finalBundlesavedInstanceState){
super.onCreate(savedInstanceState);
//这里问题1的得到解答
//在manifest中配置的元数据信息,so库的名称
//该库在这里得到了加载
onLoadNativeLibraries();
sContext= this ;
.mHandler= Cocos2dxHandler( );
//helper和这个activity绑定了
Cocos2dxHelper.init( );
//这里问题2得到解答
//这个native方法调用过程中
//调用了cocos_android_app_init(env,thiz);初始化了一个applicaton
.mGLContextAttrs=getGLContextAttrs();
//初始化,下面细看
.init();
//接下来的两个helper用来动态往mFrameLayout中添加删除相应的view
if (mVideoHelper==null){
mVideoHelper= Cocos2dxVideoHelper( ,mFrameLayout);
}
(mWebViewHelper==null){
mWebViewHelper= Cocos2dxWebViewHelper(mFrameLayout);
}
}
2.init
init(){
//创建父容器FrameLayout
//FrameLayout
ViewGroup.LayoutParamsframelayout_params=
ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
mFrameLayout= FrameLayout( );
mFrameLayout.setLayoutParams(framelayout_params);
//添加了一个编辑框,但是是干嘛用的?问题3
//Cocos2dxEditTextlayout
ViewGroup.LayoutParamsedittext_layout_params=
ViewGroup.LayoutParams.WRAP_CONTENT);
Cocos2dxEditTextedittext= Cocos2dxEditText( );
edittext.setLayoutParams(edittext_layout_params);
//...addtoFrameLayout
mFrameLayout.addView(edittext);
//添加一个glSurfaceView到容器
//Cocos2dxGLSurfaceView
.mGLSurfaceView= .onCreateView();
//...addtoFrameLayout
mFrameLayout.addView( .mGLSurfaceView);
//SwitchtosupportedOpenGL(ARGB888)modeonemulator
(isAndroidEmulator())
.mGLSurfaceView.setEGLConfigChooser(8,8,16,0);
//设置glSurfaceView的render
.mGLSurfaceView.setCocos2dxRenderer( Cocos2dxRenderer());
.mGLSurfaceView.setCocos2dxEditText(edittext);
//通过activity展现出来
//Setframelayoutasthecontentview
setContentView(mFrameLayout);
B. Cocos2dxGLSurfaceView.java

5
//这个类的代码就不贴了,不过看了之后应该一些疑惑就得到了解答
//加速器事件,touch事件,key事件的分发都从这里继续派发
//输入法的弹出或者关闭处理也在这里,这里解答了问题3,用那个编辑框来做输入法弹出相关的逻辑
//因为InputMethodManager的showSoftInput,hideSoftInputFromWindow需要相应的参数
//同时,注意这点在onResume时设置的renderMode,setRenderMode(RENDERMODE_CONTINUOUSLY);

C. Cocos2dxRenderer.java

45
//这个类关注几个callback就好
1.onSurfaceCreated
这里调用了一个本地方法nativeInit,负责给导演设置了glview并调用了application的run方法
联想到linux的实现,看样子android的大循环也开启了,但令人感到奇怪的是,android的application
的run方法调用了applicationDidFinishLaunching而没哟类似linux的大循环。。。问题4
吼吼,继续走起
2.onSurfaceChanged
//屏幕方向变化等导致的回调
3.onDrawFrame
@Override
onDrawFrame(finalGL10gl){
/*
*Noneedtousealgorithmindefault(60FPS)situation,
*sinceonDrawFrame()wascalledbysystem60timespersecondbydefault.
*/
//android本身是一秒种onDrawFrame才被调用60次,
//也就是fps大于等于60次的都按fps=60来算了,高了也做不到,受限于onDrawFrame这个方法
(sAnimationInterval<=1.0/60*Cocos2dxRenderer.NANOSECONDSPERSECOND){
Cocos2dxRenderer.nativeRender();
} else {
//fps小于60的情况
final long now=System.nanoTime();
interval=now- .mLastTickInNanoSeconds;
(interval<Cocos2dxRenderer.sAnimationInterval){
try {
Thread.sleep((Cocos2dxRenderer.sAnimationInterval-interval)/Cocos2dxRenderer.NANOSECONDSPERMICROSECOND);
catch (finalExceptione){
}
}
/*
*RendertimeMUSTbecountedin,ortheFPSwillslowerthanappointed.
*/
.mLastTickInNanoSeconds=System.nanoTime();
Cocos2dxRenderer.nativeRender();
}
}
4.Cocos2dxRenderer.nativeRender
JNIEXPORT JNICALLJava_org_cocos2dx_lib_Cocos2dxRenderer_nativeRender(JNIEnv*env){
cocos2d::Director::getInstance()->mainLoop();
}
//豁然开朗
//onDrawFrame相当于一个循环了,mainLoop在这个循环中被调用
//逻辑本质上和linux的分析是一样的
//问题4得到解答

D. javaactivity-android.cpp

//在上面的分析中这个文件已经都涉及到了

小结

  • 在proj.androd工程里面,几个注意的细节:manifest里面定义了so库的名称并在cocos提供的Cocos2dxActivity onCreate里得到加载;jni里面的main.cpp里面有个奇怪的方法并在那里new了一个application对象,而这个方法同样是被Cocos2dxActivity onCreate方法间接调用到的。

  • 在目录cocos/platform/android/下,有用信息很丰富,包含了:

  • 很多跨平台实现细节里面的关于android平台的特地实现,如application,fileUtil,glView等

  • 对接android平台的事件源,在java层设置事件监听,监听器被回调,jni调用到native层,native层通过事件分发器发送事件。这个过程基本都和glSurfaceView关联了。这里的事件包括加速器事件,touch事件,key事件。

  • 对比linux平台的那个大循环,android的大循环本质思路还是一样的。只是那个大循环被Cocos2dxRenderer.java onDrawFrame代替。关于glSurfaceView GLSurfaceView.Renderer的更多信息请参考扩展阅读里面的链接

  • 提供了android平台上关于音频播放相关的两个封装。而且是供native方法调用的。具体用法暂没细看。

  • 提供了android平台上播放视频和打开网页相关的分装,通过动态往Cocos2dxActivity的contentView里面添加删除videoView或者webView来实现。具体用法暂没细看。

  • 提供了本地数据库存储的包装实现。

  • 提供了很多helper类或者功能,弹出对话框,弹出输入法框,获取应用包名等。

  • 提一提android程序是怎么退出的:menuCloseCallback --> Director::getInstance()->end() --> (android平台的实现)GLViewImpl::end() --> (Java_org_cocos2dx_lib_Cocos2dxHelper.cpp)terminateProcessJNI --> (Cocos2dxHelper.java) terminateProcess --> android.os.Process.killProcess(android.os.Process.myPid());

  • 那android程序怎么起来的呢。。。Zygote and fork,that's a long story

  • 看这部分代码有个细节要注意,这里涉及到jni,但jni也没那么可怕,记住调用方向就好,java调用c++的方法时该方法要用native修饰,c++调用java一般是通过jnihelper来调用java层的xxHelper的static方法

  • 关于在Cocos2dxActivity contenView里面有一个隐藏的Cocos2dxEditText这里应该还有不少故事。

扩展阅读

http://developer.android.com/reference/android/opengl/GLSurfaceView.html

http://developer.android.com/reference/android/opengl/GLSurfaceView.Renderer.html

OpenGL例子:https://github.com/cheyiliu/test4opengles

http://developer.android.com/training/articles/perf-jni.html

猜你在找的Cocos2d-x相关文章