Cocos2d-x 之 HelloWorld

从这里开始

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

  • 初始化OpenGL
//初始化OpenGL
void 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);
}
  • 初始化游戏
//程序初始化
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;
}
// 扩展其它包
static int register_all_packages()
{
    return 0; //flag for packages manager
}
  • 游戏进入后台时调度
// 游戏进入后台运行时
void AppDelegate::applicationDidEnterBackground() {
    //停止动画
    Director::getInstance()->stopAnimation();

    // 暂停背景音乐
    // SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
}
  • 游戏恢复运行时调度
// 游戏恢复运行时
void AppDelegate::applicationWillEnterForeground() {
    //开始动画
    Director::getInstance()->startAnimation();

    // 恢复背景音乐
    // SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
}

Cocos2d-x 架构

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

我们可以看到,架构的最下层是操作系统,中间层是 cocos 引擎,声音引擎,物理引擎和脚本引擎等,最上面的一层才是我们自己写的代码。
下面我们再看一下cocos的组织结构,同样这张图来自官网教程:
image

  • 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; \
    } \
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值