Cocos2d-3.x的HelloWorld工程分析(一)
一 .下载及编译HelloWorld
http://www.cocos2d-x.org/download/version#Cocos2d-x
1.前往官方网站下载框架,这里我们以3.11版本框架为例
2.解压文件夹,打开工程
3.卸载掉C++之外的工程
4.进行编译 F7进行编译
二.HelloWorld解析
1.我们搜索并打开 main.cpp,这就是我们游戏的主函数
#include "main.h"
#include "../Classes/AppDelegate.h"
USING_NS_CC;
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// create the application instance
AppDelegate app;//声明一个对象
return Application::getInstance()->run();//调用getInstance()返回对象,然后调用方法<pre><pre name="code" class="cpp">
}
2.我们首先查看一下继承关系
3.介绍一下个各类,首先是ApplicationProtocol这个类,类中所有方法都是纯虚函数,
也就是说我们子类必须去实现(不会的同学可以自行学习一下)
0.1 ApplicationProtocol类
因为WINDOWS和ANDROID定义为宏,所以我们不仅可以使用这些关键字在枚举(平台)。
因此,“操作系统”前缀被添加为避免冲突与系统的定义的宏
enum class Platform
{
OS_WINDOWS,/** Windows */
OS_LINUX,/** Linux */
OS_MAC,/** Mac*/
OS_ANDROID,/** Android */
OS_IPHONE,/** Iphone */
OS_IPAD,/** Ipad */
OS_BLACKBERRY,/** BLACKBERRY */
OS_NACL,/** Nacl */
OS_EMSCRIPTEN,/** Emscripten */
OS_TIZEN,/** Tizen */
OS_WINRT,/** Windows Store Applications */
OS_WP8/** Windows Phone Applications */
};
//实现导演和场景初始化的代码--------------由AppDelegate::applicationDidFinishLaunching()实现
// * @return true Initialize success, app continue.
//* @return false Initialize failed, app terminate.
virtual bool applicationDidFinishLaunching() = 0;
//这个函数当应用置于后台会被调用-------AppDelegate::applicationDidEnterBackground() 实现
virtual void applicationDidEnterBackground() = 0;
//这个函数当应用置于前台会被调用------AppDelegate::applicationWillEnterForeground()
virtual void applicationWillEnterForeground() = 0;
//通过导演限制FPS-----Application::setAnimationInterval()
virtual void setAnimationInterval(float interval) = 0;
/** Subclass override the function to set OpenGL context attribution instead of use default value.
* And now can only set six attributions:redBits,greenBits,blueBits,alphaBits,depthBits,stencilBits.
* Default value are(5,6,5,0,16,0), usually use as follows:
* void AppDelegate::initGLContextAttrs(){
* GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};
* GLView::setGLContextAttrs(glContextAttrs);
* }
*/
//子类override 这个函数来设置OpenGL 上下文属性代替它的默认值
//现在只能设置6个属性redBits greenBits,blueBits,alphaBits,depthBits stencilBits。
//空实现,在Application::run()调用
virtual void initGLContextAttrs() {}
//获取当前语言config------Application::getCurrentLanguage()实现
// @return Current language config.
virtual LanguageType getCurrentLanguage() = 0;
//获取当前平台编码iso 639-1 code----Application::getCurrentLanguageCode()实现
////@return Current language iso 639-1 code.
virtual const char * getCurrentLanguageCode() = 0;
//获取目标平台----Application::getTargetPlatform()实现
virtual Platform getTargetPlatform() = 0;
//获取版本----Application::getVersion()实现
virtual std::string getVersion() = 0;
//打开url默认浏览器----Application::openURL(const std::string &url)实现
//@param String with url to open.
//@return True if the resource located by the URL was successfully opened; otherwise false.
virtual bool openURL(const std::string &url) = 0;
0.2Application类介绍,继承于ApplicationProtocol,实现了一些方法
//获取当前类的实例
// @return Current application instance pointer.
static Application* getInstance();
//弃用的方法,用 getInstance()代替
CC_DEPRECATED_ATTRIBUTE static Application* sharedApplication();
/* override functions */
//覆盖函数
virtual void setAnimationInterval(float interval);
virtual LanguageType getCurrentLanguage();
virtual const char * getCurrentLanguageCode();
//当前平台
virtual Platform getTargetPlatform();
//当前版本
virtual std::string getVersion() override;
//打开url的浏览器
// @param String with url to open.
// @return true if the resource located by the URL was successfully opened; otherwise false.
virtual bool openURL(const std::string &url);
//设置资源根目录
//@deprecated Please use FileUtils::getInstance()->setSearchPaths() instead.
CC_DEPRECATED_ATTRIBUTE void setResourceRootPath(const std::string& rootResDir);
//获取资源路径
//@deprecated Please use FileUtils::getInstance()->getSearchPaths() instead.
CC_DEPRECATED_ATTRIBUTE const std::string& getResourceRootPath(void);
void setStartupScriptFilename(const std::string& startupScriptFile);
const std::string& getStartupScriptFilename(void)
{
return _startupScriptFilename;
}
0.3AppDelegate类,继承Application,实现Application没有实现的一些方法
//初始化openGl属性
virtual void initGLContextAttrs();
//实现ApplicationProtocol的纯虚函数
virtual bool applicationDidFinishLaunching();
virtual void applicationDidEnterBackground();
virtual void applicationWillEnterForeground();
三.HelloWorld从main函数开始,基本函数的调用
1.Main中函数
2.声明AppDelegate app;对象
3.Application::getInstance()//单例模式,返回自己类的静态对象
返回Application * Application::sm_pSharedApplication = 0;
4.调用Application::run()//应用类的方法run方法让子类来实现
// Initialize instance and cocos2d.
if (!applicationDidFinishLaunching())
{
return 1;
}
5.调用AppDelegate::applicationDidFinishLaunching()
四、对于这些调用的疑问
1.疑问?为什么创建AppDelegate app;对象,不知道大家仔细思考了没有,我们把这个对象去掉看看,可以编译通过的。
运行一下 挂掉了,为什么挂掉了呢
答:
Application * Application::sm_pSharedApplication返回的这个单例对象空了,那这个对象什么时候进行赋值的呢?
Application构造函数
Application::Application()
: _instance(nullptr)
, _accelTable(nullptr)
{
_instance = GetModuleHandle(nullptr);
_animationInterval.QuadPart = 0;
CC_ASSERT(! sm_pSharedApplication);
sm_pSharedApplication = this;//这个this是什么呢?哦,当前类的对象那是谁呢?AppDelegate app;
}
2.代理模式
-组成:
- 抽象角色:通过接口或抽象类声明真实角色实现的业务方法。//我们的 ApplicationProtocol
- 代理角色:实现抽象角色,是真实角色的代理, //Application
- 通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
- 真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。//AppDelegate
3.代理模式的好处内容实现者和调用者进行分离。
AppDelegate app; //对象声明的时候讲getInstance返回的静态对象指向子类
Application::getInstance()->run(); //getInstance返回的是父类指向子类的对象
//run()方法也是它父类的方法-->调用子类AppDelegate::applicationDidFinishLaunching
//自己只负责调用接口去运行,实现方面交给了父类,
int Application::run()
{
PVRFrameEnableControlWindow(false);
// Main message loop:
LARGE_INTEGER nLast;
LARGE_INTEGER nNow;
QueryPerformanceCounter(&nLast);
initGLContextAttrs();
// Initialize instance and cocos2d.
if (!applicationDidFinishLaunching()) //调用子类方法,这也就是我们helloworld的入口了
{
return 1;
}
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
// Retain glview to avoid glview being released in the while loop
glview->retain();
while(!glview->windowShouldClose())
{
QueryPerformanceCounter(&nNow);
if (nNow.QuadPart - nLast.QuadPart > _animationInterval.QuadPart)
{
nLast.QuadPart = nNow.QuadPart - (nNow.QuadPart % _animationInterval.QuadPart);
director->mainLoop();
glview->pollEvents();
}
else
{
Sleep(1);
}
}
// Director should still do a cleanup if the window was closed manually.
if (glview->isOpenGLReady())
{
director->end();
director->mainLoop();
director = nullptr;
}
glview->release();
return 0;
}
下面介绍一下