初识cocos2d-x-从环境配置到整体框架

时间:2023-03-09 13:19:25
初识cocos2d-x-从环境配置到整体框架

前言

ACM生涯在带着些许遗憾中结束了。春招的时候找了一份游戏开发的工作,现在学习cocos2dx中。

从ACM竞赛到实际项目开发的学习,第一感觉就是不适应,虽然感觉实际项目的确要比ACM简单的多。最近花了几天时间,研究了下cocos2dx,现在做个总结。

一、简介

1. 学习时间

2014年4月15日 至 2014年4月19

2. 学习内容

 1Cocos2d-x环境搭建,主要是Android开发环境的搭建;

 2理解Cocos2d-x项目创建、编译、运行以及项目移植过程;

3Cocos2d-x中demo主要框架及部门源码的学习。

二、主要学习内容

2.1 环境搭建

2.1.1 项目创建

1下载Cocos2d-x-2.1.4源码,安装好Python27,可以通过create_project.py创建Cocos2d-x项目,其项目在project目录下。执行CMD,先找到create_project.py 路径,再运行如下指定完成创建:

“python create_project.py -project HelloWorld -package com.cocos2d-x.org -language cpp”。

2安装好vs2010,也可以创建Cocos2d-x项目,但是由于版本问题,运行Cocos2d-x-2.1.4中的install-templates-msvc.bat不能在vs2010生成Cocos2d-x项目创建控件,因此我没有实现用vs2010创建项目。

2.1.2项目移植

首先安装好cygwin、NDK、ADT,然后打开cygwin.bat,执行:“cd /cygdrive/+ 项目proj.android目录”,在执行指定:“./build_native.sh”。最好连上手机,用ADT中的Eclipse打开项目,编译、执行即可。

 

 

2.2 几点理解

2.2.1 项目移植

1利用cygwin模拟的Linux环境,执行项目.sh脚本:将游戏所需配置文件从resource(共享文件)中复制到.android下assets文件中。

2编译Cocos2d-x中相关联的cpp文件,并产生本地动态链接库.os文件,这个文件为JNI提供所以c/c++本地方法。此过程会产生obj中间文件夹,和保存.so文件的libs文件夹。

3NDK实现交叉编译,产生so文件,并将so文件和Java程序一起打包,生成apk文件。

 

2.2.2 JNI

概念:JNI就是实现Java和c/c++交互的一种接口。

1Java代码部分:

ajava静态模块中,通过System.loadLibrary()来引用JNI库;

b声明在JNI中调用的函数,用native修饰。

 

2c++部分:

aSystem.loadLibrary()执行后首先调用c++中的JNI_OnLoad()方法,先获取并保存JAVAVM的值(因为线程可能不定),其中包括Java的版本信息,然后通过JAVAVM指针,获取当前应用程序所在的线程JNIEnv。c++通过JNIEnv可以操作JAVAVM中的类和方法;

b调用android::AndroidRuntime::registerNativeMethods() 注册native函数指针。即告诉那些JNI那些方法是native方法,并为JNI提供这些函数的函数指针;

c构造JNINativeMethod[],将JNI函数和Java中的函数实现映射。其中函数签名以“(M)N”的方式,M表示函数参数,N表示返回值;

d实现JNI函数。

 

3编译和运行:

agcc等支持c++编译工具,编译并生成动态连接库,如.os文件等;

b在Java的静态模块中加载动态链接库,再将整个程序进行编译、运行。

 

4JNI与NDK的区别:

aNDK是集成环境(新版本NDK自带c++编译环境,或者使用cygwin编译),可编译产生动态链接库(.so),实现Android的JNI开发,并且能将.so和Java一起打包成apk文件。

bJNI是一套接口,本身不具有c++编译功能,相当于实现Java与本地c/c++交互的协议。

 

5几个细节:

ajava static 代码块可以有多个,独立于类之外,JavaVM只会执行他们一次;

bJNI改变了Android应用程序的框架:

I. 原来的框架:

Application code -> Framework Classes -> System Library and Linux Kernel

II. 引入JNI后:

Application code -> JNI -> System Library and Linux Kernel

cJava容易反编译,而c/c++难,引入JNI更安全,不易破译。

 

 

2.2.3 Cygwin、NDK、ADT、交叉编译的理解

1Cygwin:在windows平台上模拟UNIX/Linux环境,为NDK提供c/c++编译功能。

2NDK:为Android开发实现JNI功能,并将本地方法编译、生成动态链接库.so文件,并将so和Java应用一起打包生成apk。

3ADT:Android开发工具,对于用Eclipse开发Android来说就是Eclipse的插件。

4交叉编译:就是在一个平台中产生另一个平台的可执行文件。

 

2.3 demo整体框架学习

2.3.1 win32主要框架

1程序入口:从main函数开始。

a创建AppDelegate一个实例app,app即为游戏本身。AppDelegate是CCApplication单例类的子类,在创建app时,同是也创建了CCApplication的一个全局唯一的对象。CCApplication中静态指针sm_pSharedApplication将指向自身唯一的对象,并通过sharedApplication()函数返回这个指针。

b通过sharedOpenGLView()实例化一个唯一的CCEGLView对象,并调用其中Create()方法,创建游戏窗口,再在Create()中调用initGL()方法,初始化openGL引擎。CCEGView对象还提供了处理鼠标、键盘事件的方法。

c调用CCApplication的run()方法,构造游戏初始场景,并进入主循环。

 

2CCApplication::run()方法:

a获取硬件频率和硬件计数器的计数,为控制游戏延迟(帧数)做准备。

b以动态多态调用子类AppDelegate中实现的applicationDidFinishLaunching()方法,创建唯一的导演类对象、设置游戏帧数,建立游戏初始场景,并让唯一的导演类对象管理这个场景。

c显示主窗口。

d消息驱动方式进入主循环,这里主要是采用动态多态的方式,调用子类CCDisplayLinkDirector实现的方法mainLoop()方法,处理游戏的一帧。整个循环受windows消息控制,当PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)方法没有检查到windows消息时,处理一帧。否则,如果得到的是关闭窗口的信息,则关闭窗口,若不是,则调用applicationDidEnterBackground(),进入后台,再处理消息,到消息处理完,再调用applicationWillEnterForeground()返回游戏,循环继续。

处理消息,

e处理windows消息。

3CCDisplayLinkDirector::mainLoop()方法:

a) 检查游戏是否下一帧结束,如果是则清理所以资源,否则进入b。

b) 调用drawScene()画一个新场景,然后进行资源回收。

c) 弹出自动回收池,使得这一帧被放入自动回收池的对象全部释放。

 

4drawScene()方法:

a计算延时。Updata实现时间相关的逻辑,并处理延迟时间,否则游戏中的动作处理将会受硬件的影响。

b在glClear之前,安装优先级调度update(),更新定时器。

c清理缓存,为绘图计算提供资源。

d为切换场景做准备。告诉引擎还有下一个场景需要绘制,setNextScene()保存下次处理的场景。

e保存当前图片矩阵。

f绘制子节点的场景。

g绘制通知节点。主要是用来做特殊显示用,如fps等信息。游戏运行时,会显示这些数据。

h绘制设置setDisplayStats(true)之后显示的东西。

i恢复当前矩阵

j统计帧数。我不知道为什么会有这个函数,因为用的很少。

k更新缓存区。这里使用了OpenGL的双缓存机制。

l更新统计信息,计算fps。

2.3.2几点理解

1CC_DLL宏定义中,_declspec(dllexport)声明一个类(或函数)为导出类,这个类(或函数)编译后将产生dll文件,调用时需要从dll中导出;而_declspec(dllimport)是现实声明某个类(或函数)为dll类,这样编译器就能够对调用语句优化,告诉连接器不用产生Thunk,而直接产生一个间接调用。

2Assert - 断言:使用断言可以创建更稳定,品质更好且不易于出错的代码。当需要在一个值为FALSE时中断当前操作的话,可以使用断言。单元测试必须使用断言。除了类型检查和单元测试外,断言还提供了一种确定各种特性是否在程序中得到维护的极好的方法。

三、心得体会

本次学习重点是cocos2d-x的环境配置、跨平台开发的原理、程序移植的原理,以及demo源码的理解。经过为期4天的学习,我基本上完成了计划书上的学习内容。对cocos2d-x的跨平台开发、JNI、NDK、交叉编译等知识有了一个大概的理解。也熟悉了cocos2d-x的创建、移植等操作,了解了cocos2d-x的整体框架。

通过本次学习,提升了我对cocos2d-x的2d游戏开发的认识,但也有很多东西需要加强学习,比如openGL等。对于源码的理解也要加深,至少要能满足游戏开发的需要才行。还有些和cocos2d-x不太相关的知识点,应该暂时先放一放,这段时间的重点要学习cocos2d-x,而不是windows的通信。