Cocos2d-x之HelloWorld

来源:互联网 发布:知乎补充回答 编辑:程序博客网 时间:2024/05/18 01:49

Cocos2d-x是基于OpenGL实现 的,游戏启动起点是Cocos2d中定义的程序类Application,在每个cocos2d项目创建时,引擎会自动给我们创建一个AppDelegate类,这个类就是继承Application类的,游戏启动就是从这个类开始的,我们在这个类里初始化OpenGL,一些基本设置和创建一个场景并运行。在这个类里主要实现以下四个方法:

1、初始化OpenGL

<span style="font-size:18px;">//初始化OpenGLvoid AppDelegate::initGLContextAttrs(){    //set OpenGL context attributions,now can only set six attributions:    //red,green,blue,alpha,depth,stencil    GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};    GLView::setGLContextAttrs(glContextAttrs);}</span>

2、初始化游戏

<span style="font-size:18px;">//程序初始化bool AppDelegate::applicationDidFinishLaunching() {    // 初始化导演    auto director = Director::getInstance();//初始OpenGL视口    auto glview = director->getOpenGLView();//设置视口大小    if(!glview) {#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)        glview = GLViewImpl::createWithRect("Demo1", Rect(0, 0, designResolutionSize.width, designResolutionSize.height));#else        glview = GLViewImpl::create("Demo1");#endif        director->setOpenGLView(glview);    }    // 是否显示FPS    director->setDisplayStats(true);    // 设置 FPS.    director->setAnimationInterval(1.0 / 60);    //自动适配    glview->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::NO_BORDER);    Size frameSize = glview->getFrameSize();    // if the frame's height is larger than the height of medium size.    if (frameSize.height > mediumResolutionSize.height)    {                director->setContentScaleFactor(MIN(largeResolutionSize.height/designResolutionSize.height, largeResolutionSize.width/designResolutionSize.width));    }    // if the frame's height is larger than the height of small size.    else if (frameSize.height > smallResolutionSize.height)    {                director->setContentScaleFactor(MIN(mediumResolutionSize.height/designResolutionSize.height, mediumResolutionSize.width/designResolutionSize.width));    }    // if the frame's height is smaller than the height of medium size.    else    {                director->setContentScaleFactor(MIN(smallResolutionSize.height/designResolutionSize.height, smallResolutionSize.width/designResolutionSize.width));    }//扩展其它包    register_all_packages();    //创建场景    auto scene = HelloNode::createScene();    //运行场景    director->runWithScene(scene);    return true;}</span>
<span style="font-size:18px;">// 扩展其它包static int register_all_packages(){    return 0; //flag for packages manager}</span>

3、游戏进入后台时调度

<span style="font-size:18px;">// 游戏进入后台运行时void AppDelegate::applicationDidEnterBackground() {//停止动画    Director::getInstance()->stopAnimation();    // 暂停背景音乐    // SimpleAudioEngine::getInstance()->pauseBackgroundMusic();}</span>

4、游戏恢复运行时调度

<span style="font-size:18px;">// 游戏恢复运行时void AppDelegate::applicationWillEnterForeground() {//开始动画    Director::getInstance()->startAnimation();    // 恢复背景音乐    // SimpleAudioEngine::getInstance()->resumeBackgroundMusic();}</span>

我们看一下Cocos2d引擎的架构,下面这张图来自官网:


我们可以看到,架构的最下层是操作系统,中间层是cocos引擎,声音引擎,物理引擎和脚本引擎等,最上面的一层才是我们自己写的代码。

下面我们再看一下cocos的组织结构,同样这张图来自官网教程:


Director是cocos的大总管,它主要的作用是在不同的游戏场景中切换,当然还有其它的工作,比如派发事件,播放和停止动画,取位图缓存、计数引用管理等等,还有我们在AppDelegate中的很多初始化工作也是Director完成的。总之Director是把控游戏全局的一个类,它是一个单例类,游戏中有且只有一个Director类。

Scene顾名思义就是一个场景,cocos把游戏划分为一个场景,比如开始场景,战斗场景,结束场景等,事实上很多游戏引擎都会采用这种方式来管理游戏,比如Unity也是。这种方式不仅直观容易理解,也使得游戏更容易管理。Scene只是一个虚拟场景,我们不会把显示对象加到Scene里面去,而是加到一个Layer上,然后再把Layer加到Scene上,一个Scene可以有很多Layer。

Layer是一个层,一般我们显示对象加到其上面,再把层加到场景上。一个场景可以添加多个层,后添加的层在先添加的层上面。一般我们在游戏中创建一个场景不会直接继承自Scene,而是继承自Layer,然后在Layer里面写一个静态方法CreateScene来创建一个场景,并创建一个自己(层)的实例加到场景上。

Node是所有显示对象的根结点,Sprite,DrawNode,Label等等都会继承它(当然也可能继承其它类,C++是多重继承的)。

下面我们来看一下一个HelloWorld的场景,以了解cocos2d的组织结构,这个类实现一个矩形和一个点不断地旋转。

#include "HelloWorldScene.h"//使用Cocos2d命名空间//using namespace cocos2d;USING_NS_CC;//静态方法,创建一个场景Scene* HelloWorld::createScene(){    // 创建场景    auto scene = Scene::create();        // 实例化自己,创建一个层    auto layer = HelloWorld::create();    // 把层加到场景上    scene->addChild(layer);    // 返回场景    return scene;}// 初始化层// 这个方法会在Layer的create里面被调用bool HelloWorld::init(){//调用父类方法初始化层    if ( !Layer::init() )    {        return false;    }    /*下面代码实现我们自己的功能*///获得屏幕的大小    Size visibleSize = Director::getInstance()->getVisibleSize();//获得屏幕的原点    Vec2 origin = Director::getInstance()->getVisibleOrigin();//创建一个矩形auto rect=DrawNode::create();rect->drawRect(Vec2(0,0),Vec2(0,100),Vec2(100,100),Vec2(100,0),Color4F(0.1,0.2,0.3,1));//设置位置,相对于它的父结点rect->setPosition(origin.x+visibleSize.width/2,origin.y+visibleSize.height/2);//设置锚点(百分比)rect->setAnchorPoint(Vec2(0.5,0.5));rect->setContentSize(Size(100,100));//添加到父结点this->addChild(rect);//创建一个点auto dot=DrawNode::create();dot->drawDot(Vec2(0,0),10,Color4F(1,0,0,0.5));//设置位置,相对坐标dot->setPosition(Vec2::ZERO);//锚点对点不起作用dot->setAnchorPoint(Vec2(0.5,0.5));//添加到父结点rect->addChild(dot);//调度器,其回调函数在游戏运行的每一帧里都会被调用一次schedule([dot,rect](float f){rect->setRotation(rect->getRotation()+1);Vec2 p=dot->convertToWorldSpace(Vec2(0,0));log("%f,%f",p.x,p.y);},"test");/****************************/    return true;}

我们再看一下.h文件

#ifndef __HELLOWORLD_SCENE_H__#define __HELLOWORLD_SCENE_H__#include "cocos2d.h"class HelloWorld : public cocos2d::Layer{public:<span style="white-space:pre"></span>//创建场景的静态方法createScene    static cocos2d::Scene* createScene();//实现初始化方法init    virtual bool init();        // 实现静态方法create    CREATE_FUNC(HelloWorld);};#endif 

我们看到在这个类里我们实现了三个方法,一个创建场景的静态方法,一个创建层的静态方法,一个初始化层的实例方法。CREATE_FUNC(类名)是cocos定义的一个宏,一般我们直接用这个宏的创建层就可以了,如果有需要我们也可以自己手动实现这个方法,比如我们在创建层的时候需要传参数进来,就必须要自己写了。我们看一下这个宏的定义,我们自己实现这个方法也是要根据它的写法来的。

#define CREATE_FUNC(__TYPE__) \static __TYPE__* create() \{ \    __TYPE__ *pRet = new(std::nothrow) __TYPE__(); \    if (pRet && pRet->init()) \    { \        pRet->autorelease(); \        return pRet; \    } \    else \    { \        delete pRet; \        pRet = nullptr; \        return nullptr; \    } \}



0 0