1
2
3
4
5
6
7
8
9
10
11
12
13
|
public
class
HelloLua
extends
Cocos2dxActivity{
protected
void
onCreate(Bundle savedInstanceState){
super
.onCreate(savedInstanceState);
}
public
Cocos2dxGLSurfaceView onCreateGLSurfaceView() {
return
new
LuaGLSurfaceView(
this
);
}
static
{
System.loadLibrary(hellolua);
}
}
|
从上面的代码,启动Activity是继承Cocos2dxActivity的,在游戏启动时,Activity首先会执行静态代码块,加载libhellolua.so库,这个动态链接库是在用NDK编译的时候生成的;然后就是执行onCreate方法,这里调用了父类Cocos2dxActivity的onCreate方法。 Cocos2dxActivity在
1
|
$(sourcedir)cocos2dxplatformandroidjavasrcorgcocos2dxlibCocos2dxActivity.java
|
中定义,其OnCreate方法代码如下:
1
2
3
4
5
6
7
8
9
|
protected
void
onCreate(
final
Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
sContext =
this
;
this
.mHandler =
new
Cocos2dxHandler(
this
);
this
.init();
Cocos2dxHelper.init(
this
,
this
);
}
|
这里主要是执行初始化过程,Cocos2dxHandler主要处理显示Dialog的消息,Cocos2dxHelper是个辅助类,我们主要看init()方法,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
public
void
init() {
// FrameLayout
ViewGroup.LayoutParams framelayout_params =
new
ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT);
FrameLayout framelayout =
new
FrameLayout(
this
);
framelayout.setLayoutParams(framelayout_params);
// Cocos2dxEditText layout
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);
// ...add to FrameLayout
framelayout.addView(edittext);
// Cocos2dxGLSurfaceView
this
.mGLSurfaceView =
this
.onCreateView();
// ...add to FrameLayout
framelayout.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(framelayout);
}
|
1
2
3
|
public
Cocos2dxGLSurfaceView onCreateView() {
return
new
Cocos2dxGLSurfaceView(
this
);
}
|
1
|
$(sourcedir)cocos2dxplatformandroidjavasrcorgcocos2dxlibCocos2dxGLSurfaceView.java
|
中定义,它继承自opengl中类GLSurfaceView。GLSurfaceView的核心就是Renderer,初始化时会调用Renderer的onSurfaceCreated方法,每一帧的绘制是通过调用Renderer的onDrawFrame方法。Cocos2dxGLSurfaceView的Renderer是一个Cocos2dxRenderer对象,类Cocos2dxRenderer在
1
|
$(sourcedir)cocos2dxplatformandroidjavasrcorgcocos2dxlibCocos2dxRenderer.java
|
中定义,其方法onSurfaceCreated代码如下:
1
2
3
4
|
public
void
onSurfaceCreated(
final
GL10 pGL10,
final
EGLConfig pEGLConfig) {
Cocos2dxRenderer.nativeInit(
this
.mScreenWidth,
this
.mScreenHeight);
this
.mLastTickInNanoSeconds = System.nanoTime();
}
|
这里主要调用了一个方法nativeInit,nativeInit被声明为:
1
|
private
static
native
void
nativeInit(
final
int
pWidth,
final
int
pHeight);
|
即它是一个native的函数,即该函数用C++代码中实现,关于native函数简单说,就是在java在调用C++代码实现的函数,即需要采用JNI技术(可以看成是Java与C++交互的一个协议~)。方法nativeInit对应的C++实现是在(sourcedir)samplesLuaHelloLuaproj.androidjnihelloluamain.cpp中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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();
}
else
{
.....
}
}
|
1
2
3
4
5
6
7
8
9
10
|
CCDirector* CCDirector::sharedDirector(
void
)
{
if
(!s_SharedDirector)
{
s_SharedDirector =
new
CCDisplayLinkDirector();
s_SharedDirector->init();
}
return
s_SharedDirector;
}
|
这里的CCCCDisplayLinkDirector是CCDirector的子类,方法init()做一些初始化工作:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
bool CCDirector::init(
void
)
{
setDefaultValues();
//场景相关
...
...
//管理场景的数组栈
m_pobScenesStack =
new
CCArray();
m_pobScenesStack->init();
// 一些FPS等相关的成员变量初始化
...
...
//初始化调度器对象
m_pScheduler =
new
CCScheduler();
//动作管理器对象
m_pActionManager =
new
CCActionManager();
m_pScheduler->scheduleUpdateForTarget(m_pActionManager, kCCPrioritySystem,
false
);
// touchDispatcher,KeypadDispatcher,Accelerometer等对象初始化
...
...
// CCPoolManager中实现了cocos2d-x CCObject对象的内存管理机制
CCPoolManager::sharedPoolManager()->push();
return
true
;
}
|
创建好导演对象后,Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit中调用了该对象的getOpenGLView方法:
1
|
inline CCEGLView* getOpenGLView(
void
) {
return
m_pobOpenGLView; }
|
该方法返回用于游戏绘制的CCEGLView,在init()中,m_pobOpenGLView复制为NULL。在Android平台下,这个CCEGLView其实没有什么作用,因为游戏都是绘制在Cocos2dxGLSurfaceView上的,因此方法Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit接着执行if分支:
1
2
|
CCEGLView *view = CCEGLView::sharedOpenGLView();
view->setFrameSize(w, h);
|
这里同样创建了游戏中类CCEGLView的唯一实例,类在$(sourcedir)cocos2dxplatformandroidCCEGLView.cpp中实现。接着执行
1
2
|
AppDelegate *pAppDelegate =
new
AppDelegate();
CCApplication::sharedApplication()->run();
|
创建了一个类AppDelegate对象,类AppDelegate在$(sourcedir)samplesLuaHelloLuaClassesAppDelegate.cpp中实现,类AppDelegate在各个平台之间共用的:
1
2
3
4
5
6
7
8
9
10
11
|
class
AppDelegate :
private
cocos2d::CCApplication
{
public
:
AppDelegate();
virtual ~AppDelegate();
virtual bool applicationDidFinishLaunching();
virtual
void
applicationDidEnterBackground();
virtual
void
applicationWillEnterForeground();
};
|
该类继承自CCApplication,注意类CCApplication是在$(sourcedir)cocos2dxplatformandroidCCApplication.cpp中实现的,它的实现是与平台相关的。创建AppDelegate实例的工作实质就是实例化CCApplication,它的构造函数代码如下:
1
2
3
4
5
|
CCApplication::CCApplication()
{
CCAssert(! sm_pSharedApplication, );
sm_pSharedApplication =
this
;
}
|
因此在实例化AppDelegate时,主要工作是用AppDelegate对象初始化全局变量sm_pSharedApplication。接着后面调用CCApplication::sharedApplication()->run(),相关代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
CCApplication* CCApplication::sharedApplication()
{
CCAssert(sm_pSharedApplication, );
return
sm_pSharedApplication;
}
int
CCApplication::run()
{
// Initialize instance and cocos2d.
if
(! applicationDidFinishLaunching())
{
return
0
;
}
return
-
1
;
}
|
run中调用的虚函数applicationDidFinishLaunching实质上调用的是子类AppDelegate中的applicationDidFinishLaunching,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
bool AppDelegate::applicationDidFinishLaunching()
{
//初始化director
CCDirector *pDirector = CCDirector::sharedDirector();
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(
480
,
320
, kResolutionNoBorder);
//显示FPS
pDirector->setDisplayStats(
true
);
// 设置FPS
pDirector->setAnimationInterval(
1.0
/
60
);
//创建Lua脚本引擎
CCLuaEngine* pEngine = CCLuaEngine::defaultEngine();
CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);
//加载执行lua脚本
std::string path = CCFileUtils::sharedFileUtils()->fullPathForFilename(hello.lua);
pEngine->executeScriptFile(path.c_str());
return
true
;
}
|
1
2
3
|
public
void
onDrawFrame(
final
GL10 gl) {
Cocos2dxRenderer.nativeRender();
}
|
其唯一的工作是调用了nativeRender方法,该方法是native的,其对应的实现是:
1
2
3
|
JNIEXPORT
void
JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeRender(JNIEnv* env) {
cocos2d::CCDirector::sharedDirector()->mainLoop();
}
|
即执行导演对象中的方法mainLoop:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
void
CCDisplayLinkDirector::mainLoop(
void
)
{
// 此变量决定程序是否结束
if
(m_bPurgeDirecotorInNextLoop)
{
m_bPurgeDirecotorInNextLoop =
false
;
purgeDirector();
}
else
if
(! m_bInvalid)
{
//屏幕绘制,并做一些相应的逻辑处理
drawScene();
// 释放对象管理器中CCObject 对象
CCPoolManager::sharedPoolManager()->pop();
}
}
|
这个方法就是所有平台最后真正执行的循环体。
原文地址:http://www.2cto.com/kf/201409/335933.html