【tonyfield 2013.09.04 】

参考 Linux下搭建 Cocos2d-x-2.1.4 编译环境 导入 HelloCpp 例程

1. Java 入口 HelloCpp.java

HelloCpp类很简单,因为它继承的父类 Cocos2dxActivity 揽下了所有的内部操作,并建立了和JNI各类接口的关系,显示的工作也是通过 Cocos2dxActivity 的OnCreate函数来完成的。具体可以参考其实现。

System.loadLibrary("hellocpp");这句将载入项目内的 JNI 库,执行 JNI 中 JNI_OnLoad 函数接口。

import org.cocos2dx.lib.Cocos2dxActivity;

import android.os.Bundle;

public class HelloCpp extends Cocos2dxActivity{

    protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
} static {
System.loadLibrary("hellocpp");
}
}

除了上述所述功能,如果你发布的应用是收费的,那在这个类型中还需要添加验证过程,具体请参考 Android 开发文档。

2. JNI 入口 main.cpp

main.cpp 路径是 jni/hellocpp/main.cpp,载入库时刻,JNI_OnLoad 将被调用 ,它做的很重要的事情就是保存javaVM值,通过这个值你可以在JNI空间任何地方去的有效的JNIEnv环境变量 。相反,试图保存 JNIEnv在未来调用的做法是危险的。

jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
JniHelper::setJavaVM(vm); return JNI_VERSION_1_4;
}

另一件必须完成的工作就是实现虚函数 Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit,显然 上节提到的 Cocos2dxActivity 将会调用这个函数。

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();
    }
}

函数先检查 OpenGL View 是否可以正常获得,对于 Android API版本较低的手机这个函数可能无法通过,这时,在模拟器上看到的是黑屏。你可以自己修改来是上层显示一点提示,免得用户以为是程序有问题。

下面就是最重要的事情,创建自己的应用代表(Application Delegate)实例。这个实例中你需要做的就是实现初始化,消息响应函数等接口。CCApplication::sharedApplication()->run();会帮你让程序运转起来。CCApplication 这个类很简单,也有些诡异,它继承的 CCApplicationProtocol 类型就是一个纯虚的接口定义,这个父类是为跨平台设计的。CCApplication 中有一个静态函数 sharedApplication(),始终返回最近一次创建该类型对象的 this指针。这意味着 cocos2dx 在创建完这个对象后就想把这个对象的指针交给开发者,再由开发者调用 run成员函数来运转程序。

int CCApplication::run()
{
// Initialize instance and cocos2d.
if (! applicationDidFinishLaunching())
{
return 0;
}
return -1;
}

你有理由相信你获得的这个指针实际上指向了一个 CCApplication 子类,它来完成实际的消息处理循环过程。

好了,下面来研究 AppDelegate 类型。

3. AppDelegate 类型

AppDelegate 类型在 jni/Classes/AppDelegate.h 中定义,在 jni/Classes/AppDelegate.cpp 中实现。先看下面的定义,发现原来上节的 CCApplication 在这里果然变成了AppDelegate 的父类。你需要实现 applicationDidFinishLaunching 等 3个接口函数。上节中run函数中的调用关系问题到这里迎刃而解。(我想cocos2dx是否可以象 MFC 接口那样完成的更优美一些,将接口的调用过程完全隐藏起来。)

class  AppDelegate : private cocos2d::CCApplication
{
public:
AppDelegate();
virtual ~AppDelegate(); /**
@brief 实现 CCDirector 和 CCScene 初始化代码
@return true 初始化成功, app 继续.
@return false 初始化失败, app 终止.
*/
virtual bool applicationDidFinishLaunching(); /**
@brief 当应用进入后台执行该函数
@param the pointer of the application ?? 我怎么没看到参数
*/
virtual void applicationDidEnterBackground(); /**
@brief 当应用即将进入后台执行该函数
@param the pointer of the application
*/
virtual void applicationWillEnterForeground();
};

AppDelegate的接口函数实现就像一个模版,在建立自己的应用时,你完全可以拿来主义。

bool AppDelegate::applicationDidFinishLaunching() {
// initialize director
CCDirector* pDirector = CCDirector::sharedDirector();
CCEGLView* pEGLView = CCEGLView::sharedOpenGLView(); pDirector->setOpenGLView(pEGLView); // Set the design resolution
pEGLView->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, kResolutionNoBorder); CCSize frameSize = pEGLView->getFrameSize(); vector<string> searchPath; // In this demo, we select resource according to the frame's height.
// If the resource size is different from design resolution size, you need to set contentScaleFactor.
// We use the ratio of resource's height to the height of design resolution,
// this can make sure that the resource's height could fit for the height of design resolution. // if the frame's height is larger than the height of medium resource size, select large resource.
if (frameSize.height > mediumResource.size.height)
{
searchPath.push_back(largeResource.directory); pDirector->setContentScaleFactor(MIN(largeResource.size.height/designResolutionSize.height, largeResource.size.width/designResolutionSize.width));
}
// if the frame's height is larger than the height of small resource size, select medium resource.
else if (frameSize.height > smallResource.size.height)
{
searchPath.push_back(mediumResource.directory); pDirector->setContentScaleFactor(MIN(mediumResource.size.height/designResolutionSize.height, mediumResource.size.width/designResolutionSize.width));
}
// if the frame's height is smaller than the height of medium resource size, select small resource.
else
{
searchPath.push_back(smallResource.directory); pDirector->setContentScaleFactor(MIN(smallResource.size.height/designResolutionSize.height, smallResource.size.width/designResolutionSize.width));
} // set searching path
CCFileUtils::sharedFileUtils()->setSearchPaths(searchPath); // turn on display FPS
pDirector->setDisplayStats(true); // set FPS. the default value is 1.0/60 if you don't call this
pDirector->setAnimationInterval(1.0 / 60); // create a scene. it's an autorelease object
CCScene *pScene = HelloWorld::scene(); // run
pDirector->runWithScene(pScene); return true;
} // This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground() {
CCDirector::sharedDirector()->stopAnimation(); // if you use SimpleAudioEngine, it must be pause
// SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
} // this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground() {
CCDirector::sharedDirector()->startAnimation(); // if you use SimpleAudioEngine, it must resume here
// SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
}

其中比较重要的是 CCScene *pScene = HelloWorld::scene(); 这个语句,因为它涉及到另一个自定义类型 HelloWorld。

4. HelloWorld 类型

HelloWorld 类型在 jni/Classes/HelloWorldScene.h 中定义,在 jni/Classes/HelloWorldScene.cpp 中实现。

class HelloWorld : public cocos2d::CCLayer
{
public:
// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
virtual bool init(); // there's no 'id' in cpp, so we recommend returning the class instance pointer
static cocos2d::CCScene* scene(); // a selector callback
void menuCloseCallback(CCObject* pSender); // implement the "static node()" method manually
CREATE_FUNC(HelloWorld);
};

CREATE_FUNC(HelloWorld) 展开后代码如下,基本意思就是定义静态函数create()创建HelloWorld 类对象并初始化。

static HelloWorld* create() \
{ \
HelloWorld *pRet = new HelloWorld(); \
if (pRet && pRet->init()) \
{ \
pRet->autorelease(); \
return pRet; \
} \
else \
{ \
delete pRet; \
pRet = NULL; \
return NULL; \
} \
}

在另一个静态函数 sence中,将创建一个 CCScene 对象 和 HelloWorld 对象,HelloWorld 对象被组合到 CCScene 对象中,它也是 cocos2dx内部操作的对象。

【转载请注明来自blog.csdn.net/tonyfield 谢谢 2013.09.04 】

Linux下搭建 Cocos2d-x-2.1.4 编译环境的更多相关文章

  1. [编译] 3、在Linux下搭建51单片机的开发烧写环境(makefile版)

    星期二, 10. 七月 2018 01:01上午 - beautifulzzzz 一.SDCC(Small Device C Compiler)编译环境搭建 SDCC是一个小型设备的C语言编译器,该编 ...

  2. [编译] 7、在Linux下搭建安卓APP的开发烧写环境(makefile版-gradle版)—— 在Linux上用命令行+VIM开发安卓APP

    April 18, 2020 6:54 AM - BEAUTIFULZZZZ 目录 0 前言 1 gradle 安装配置 1.1 卸载系统默认装的gradle 1.2 下载对应版本的二进制文件 1.3 ...

  3. [编译] 8、在Linux下搭建 stm8 单片机的开发烧写环境(makefile版)

    目录 一.SDCC(Small Device C Compiler)编译环境搭建 1.1.下载 1.2.编译 1.3.测试 二.Hex2Bin+命令行烧写工具配置使用 2.1.下载工具安装配置 2.2 ...

  4. Linux 下搭建jsp服务器(配置jsp开发环境)

    Linux 做为服务器的高效一直时为人所熟知的了,在linux 上搭建各种各样的服务器和开发环境也时学计算机的人常做的.以下时最近在linux配置jsp服务器的全过程,包含一些基本步骤和排错过程: 1 ...

  5. 单片机成长之路(51基础篇) - 006 在Linux下搭建51单片机的开发烧写环境

    在Linux下没有像keli那样好用的IDE来开发51单片机,开发环境只能自己搭建了. 第一步:安装交叉编译工具 a) 安装SDCC sudo apt-get install sdcc b)测试SDC ...

  6. [编译] 5、在Linux下搭建安卓APP的开发烧写环境(makefile版)—— 在Linux上用命令行+VIM开发安卓APP

    星期三, 19. 九月 2018 02:19上午 - BEAUTIFULZZZZ 0)前言 本文不讨论用IDE和文本编辑器开发的优劣,是基于以下两点考虑去尝试用命令行编译安卓APP的: 了解安卓APP ...

  7. 在linux 下为sublime Text 2 配置c#编译环境

    各位看官别笑我,在虚拟机上跑了了xp  xp里面安装了vs2008,然后电脑性能实在是太差了,所以装sublime用来编写代码,然后再统一由vs2008来调试. 说正事. 安装好sublime 之后, ...

  8. MongoDB学习笔记—Linux下搭建MongoDB环境

    1.MongoDB简单说明 a MongoDB是由C++语言编写的一个基于分布式文件存储的开源数据库系统,它的目的在于为WEB应用提供可扩展的高性能数据存储解决方案. b MongoDB是一个介于关系 ...

  9. Linux下搭建个人网站

    前不久在阿里买了一个服务器,然后开始第一次尝试搭建自己的个人网站.前端采用了bootstrap框架,后端采用的是PHP,数据库使用的是Mysql.新手第一次在linux下搭建遇见很多问题,在这里分享一 ...

随机推荐

  1. BZOJ-1007-水平可见直线-HN2008

    描写叙述 在xoy直角坐标平面上有n条直线L1,L2,-Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的. 比如,对于直线: L1:y=x; L2:y=- ...

  2. 驱动: oops

    linux驱动调试--段错误之oops信息分析 http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=29401328&id= ...

  3. python sqlalchemy-migrate 使用方法

    1:下载相关模块     pip install sqlalchemy     pip install sqlalchemy-migrate   2:创建model (model.py),这里用来绑定 ...

  4. MVC是一种用于表示层设计的复合设计模式

    它们之间的交互有以下几种:       1.当用户在视图上做任何需要调用模型的操作时,它的请求将被控制器截获.       2.控制器按照自身指定的策略,将用户行为翻译成模型操作,调用模型相应逻辑实现 ...

  5. IBM Python 技术专题

    Python 技术专题 Python 是由 Guido van Rossum 开发的,可免费获得的.是一种非常高级的解释型语言.其语法简单易懂,而且面向对象的语义功能强大又灵活,Python 可以广泛 ...

  6. Android基础【1】杀死进程(强行停止)应用程序的方法

    写在前面: 进入手机ODM已经很久,经历过几个项目项目下来,对高通.展讯.Marvell平台都进行了接触,对于我个人来说,参与手机系统项目的开发与维护,最明显的好处是可以深入的了解某一功能的具体实现过 ...

  7. vim打开文件时显示行号

    vim打开文件是,默认不提示行号. 至于显示行号的用途,因人而异 linux下一个主机可能有N个账户.对于配置分为两种:仅配置当前账户,配置所有账户 vim配置文件路径(Centos  5.5 fin ...

  8. Python之路day4

    坚持就是胜利.今天零下14度,从教室出来的路上真的很冷很冷,希望这个冬天自己不会白过,春暖花开的时候一定要给世界一个更好的自己. 原本以为day3的作业自己做得挺好的,没想到只得了B+.必须要加油了, ...

  9. solr 从零学习开始

    2010-10 目 录 1 1.1 1.2 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.3 1.3.1 1.3.2 1.4 1.4.1 1.4.2 1.4. ...

  10. UITableViewHeaderFooterView的使用+自己主动布局

    UITableViewHeaderFooterView的使用+自己主动布局 使用UITableView的header或footer复用时,假设採用自己主动布局,你会发现有约束冲突,以下这样写能够消除约 ...