我学习quick-cocos2dx-x时间也不长,刚开始都以学习quick-cocos2dx-x的samples开始的。本文以cocopush这个实例来进行解析,了解quick-cocos2dx的android基本框架。
先学习一下代码结构,结构如图:
.settings是基本配置目录;
proj.android是android工程目录,里面包含了android一个完整项目的所有文件;
proj.ios是ios工程目录;
res是资源文件目录,主要保存lua会调用到的一些图片,文字,声音等资源文件,本例中还包含framework_precompiled的压缩包,至于这个压缩包有什么作用,以后再开文章详细介绍;
scripts里面存放的是lua文件;
sources里存放AppDelegate.h和AppDelegate.cpp
我们知道lua是一种解释性脚本语言,不用编译,而有C++进行调用。
public class Cocopush extends Cocos2dxActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
CocoPushSDK.init(this);
}
static {
System.loadLibrary("game");
}
}
在android的activity里面首先调用:
CocoPushSDK.init(this);
CocoPushSDK的代码部分位于$QUICK_COCOS2DX_ROOT/lib/sdk/cocopush/cocopush_android/cocopush_android,同时需要包含$QUICK_COCOS2DX_ROOT/lib/sdk/cocopush/cocopush_android/*.jar这个库,这个参见read.md
我们在eclipse中加入CocoPush的android工程,要包含这两部分内容,否则无法编译通过的。
右键工程- Build Path - Java Build Path - Source - Link Source,注意在link的时候选择第一个选项
Update exclusion filter in other source folders to solve nesting.
同时加入库,在加入库完成以后,打开proj.android下的.classpath,确保quick-cocos2d-x-2.2.5/lib/sdk/cocopush/cocopush_android/CocoPush-0.1.6.jar已被添加,同时要保证exported="true",否则在运行的时候还是会报找不到对应的函数而崩溃。
做完这上面两步后,就要开始编译底层的C++库,因为lua语言需要由C++来调用,因此在android项目里面,类似之前的cocos2dx框架
activity启动----------通过System.loadLibrary("game");加载C++库-----------------通过jni调用,在void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thiz, jint w, jint h)这个函数里面启动AppDelegate类里面的applicationDidFinishLaunching()函数,这个过程类似与以前的cocos2dx,只是不同的是,在quick里面,我们的scene以及layout等等是通过lua来写的,而不是cocos2dx中的c++编写的。
在applicationDidFinishLaunching()函数中,
// register lua engine
CCLuaEngine *pEngine = CCLuaEngine::defaultEngine();
CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);
CCLuaStack *pStack = pEngine->getLuaStack();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
// load framework
pStack->loadChunksFromZIP("res/framework_precompiled.zip");
// set script path
string path = CCFileUtils::sharedFileUtils()->fullPathForFilename("scripts/main.lua");
#else
// load framework
if (m_projectConfig.isLoadPrecompiledFramework())
{
const string precompiledFrameworkPath = SimulatorConfig::sharedDefaults()->getPrecompiledFrameworkPath();
pStack->loadChunksFromZIP(precompiledFrameworkPath.c_str());
}
// set script path
string path = CCFileUtils::sharedFileUtils()->fullPathForFilename(m_projectConfig.getScriptFileRealPath().c_str());
#endif
size_t pos;
while ((pos = path.find_first_of("\\")) != std::string::npos)
{
path.replace(pos, 1, "/");
}
size_t p = path.find_last_of("/\\");
if (p != path.npos)
{
const string dir = path.substr(0, p);
pStack->addSearchPath(dir.c_str());
p = dir.find_last_of("/\\");
if (p != dir.npos)
{
pStack->addSearchPath(dir.substr(0, p).c_str());
}
}
string env = "__LUA_STARTUP_FILE__=\"";
env.append(path);
env.append("\"");
pEngine->executeString(env.c_str());
CCLOG("------------------------------------------------");
CCLOG("LOAD LUA FILE: %s", path.c_str());
CCLOG("------------------------------------------------");
pEngine->executeScriptFile(path.c_str());
这一部分代码,就调用了lua中的main.lua
function __G__TRACKBACK__(errorMessage)
print("----------------------------------------")
print("LUA ERROR: " .. tostring(errorMessage) .. "\n")
print(debug.traceback("", 2))
print("----------------------------------------")
end
require("app.MyApp").new():run()
main.lua中加载app.MyApp,并new一个新的对象并运行。
local MyApp = class("MyApp", cc.mvc.AppBase)
MyApp继承了cc.mvc.AppBase,在run里面调用self:enterScene("MainScene")转入MainScene执行
local MainScene = class("MainScene", function()
return display.newScene("MainScene")
end)
MainScene继承的是一个CCScene 场景对象,在lua中允许继承对象,newScene的同时会调用构造函数ctor。代码里面类似
cc.ui.UILabel.new({text = "CocoPush demo", size = 48, align = cc.ui.TEXT_ALIGN_CENTER})
:pos(display.cx, display.top - self.innerSpace*1)
:align(display.CENTER)
:addTo(self)
可以参考quick-cocos2dx的api注释,这类api其实跟以往的cocos2dx没有太大区别,只是用lua代替C++来实现,基本原理都是一样的。
像cc.ui.UILabel.new就是生成一个Label,并且定义了text,文本大小,对齐方式,位置,最后调用addTo(self),加入到layout中。
编译libgame.so 就是在windows的cmd里运行build_native.bat,另外需要设置环境变量QUICK_COCOS2DX_ROOT和ANDROID_NDK_ROOT,否则编译会报错。