cocos2d-x 基础概念介绍--导演 场景 层 精灵

cocos2d-x 基础概念介绍--导演 场景 层 精灵,第1张

概述cocos2d 基本结构 在Cocos2d-x-3.x引擎中,采用节点树形结构来管理游戏对象,一个游戏可以划分为不同的场景,一个场景又可以分为不同的层,一个层又可以拥有任意个可见的游戏节点(即对象,游戏中基本上所有的类都派生于节点类Node)。可以执行Action来修改游戏节点的属性,使其移动、旋转、放大、缩小等等。 每一个时刻都有一个场景在独立运行,通过切换不同的场景来完成一个游戏流程,游戏流程

cocos2d 基本结构

在Cocos2d-x-3.x引擎中,采用节点树形结构来管理游戏对象,一个游戏可以划分为不同的场景,一个场景又可以分为不同的层,一个层又可以拥有任意个可见的游戏节点(即对象,游戏中基本上所有的类都派生于节点类Node)。可以执行Action来修改游戏节点的属性,使其移动、旋转、放大、缩小等等。

每一个时刻都有一个场景在独立运行,通过切换不同的场景来完成一个游戏流程,游戏流程的管理由Director来执行,其基本框架类图如下:


cocos2d也采用了引用计数的方式来管理内存,基本上所有的类都派生于拥有引用计数的机制的CCObject
a.CCApplication,负责平台相关的初始化,消息处理等,是一个单件类

b.CCDirector.cocos2d-x引擎中,导演类是游戏的组织者和领导者,导演制定规则让游戏内的场景,布景,和人物角色有序的运行摄像机(CCCamera),每个节点都需要使用摄像机,当节点发生缩放,旋转,和位置变化时,都需要覆盖摄像机,让这个节点通过摄像机重新渲染。

c.CCNode,节点类,是游戏中最重要的对象,在cocos2dk中,任何可见的或不可以的游戏逻辑对象都是一个节点,节点有以下特点:

a)是一个容器,可以包含任意多个其它节点.

b)可以执行一个行为(CCAction)

c)可以执行一定时的任务回调

d)拥有坐标变换(transform)信息,如postion,scale,rotation等

e)由于一个节点可以添加任意个子节点,所有的节点组成一个树状结构,因此父节点的坐标变换会影响子节点在世界坐标系中的坐标,一个节点只能拥有一个父节点

d.CCAction,动作类,CCAtion就好像指派给CCNode的命令一样,在特定时间(或立即)内修改CCNode的属性,例如位置,旋转,缩放等

e.CCScene,场景类,和PL中的stage类似,包括可见的怪物,地形和不可见的逻辑脚本等.例如一个游戏的一个特定关卡,游戏菜单,过场动画等都是一个独立的场景.cocos2d中的场景又由不同的层(cclayer)组成.由于CCScene是CCNode的子类,因此可以可以用CCAction来修改其属性

f.cclayer类,场景中的层类,一个场景可以拥有多个层,如HUD层,游戏对象层,背景层,天空层等,层是一个可以绘制的区域.可以将ui,sprite等对象添加到其中.除此之外,层还接收输入消息,可以在层的类中处理输入消息,和CCScene一样,cclayer是CCNode的子类,也可以用CCAction来修改其属性


导演(Director)

一款游戏好比一部电影,只是游戏具有更强的交互性,不过它们的基本原理是一致的。所以在Cocos2dx中把统筹游戏大局的类抽象为导演(Director),Director是整个cocos2dx引擎的核心,是整个游戏的导航仪,游戏中的一些常用 *** 作就是由Director来控制的,比如OpenGL ES的初始化,场景的转换,游戏暂停继续的控制,世界坐标和GL坐标之间的切换,对节点(游戏元素)的控制等,还有一些游戏数据的保存调用,屏幕尺寸的获取等都要由Director类来管理控制的。

因为Director是游戏项目的总导演,会经常调用进行一些控制,所以该Director利用了单例设计模式,也就是项目里取到的director都是同一个。用sharedDirector() 方法取得Director的实例,具体的API可以参考相关文档,就不做赘述了。

class CC_DLL CCDirector : public CCObject,public TypeInfo
CCDirector *pDirector = CCDirector::sharedDirector();
   场景(Scene) 

Scene场景也是cocos2dx中必不可少的元素,游戏中通常我们需要构建不同的场景(至少一个),游戏里关卡、版块的切换也就是一个一个场景的切换,就像在电影中变换舞台和场地一样。场景的一个重要的作用就是流程控制的作用,我们可以通过Director的一系列方法控制游戏中不同的场景的自由切换。

class CC_DLL CCScene : public CCNode<pre name="code" >class CC_DLL CCNode : public CCObject
  

下面是Director控制场景的常用方法:

runWithScene( Scene *scene ) 启动游戏,并运行scene场景。本方法在主程序第一次启动主场景的时候调用。如果已有正在运行的场景则不能调用该方法;会调用pushScene-->startAnimation。
voID CCDirector::runWithScene(CCScene *pScene){    CCAssert(pScene != NulL,"This command can only be used to start the CCDirector. There is already a scene present.");    CCAssert(m_pRunningScene == NulL,"m_pRunningScene should be null");    pushScene(pScene);    startAnimation();}

pushScene( Scene *scene ) 将当前运行中的场景暂停并压入到代码执行场景栈中,再将传入的scene设置为当前运行场景,只有存在正在运行的场景时才调用该方法;
voID CCDirector::pushScene(CCScene *pScene){    CCAssert(pScene,"the scene should not null");    m_bSendCleanupToScene = false;    m_pobScenesStack->addobject(pScene);    m_pNextScene = pScene;}

replaceScene( Scene *scene ) 直接使用传入的scene替换当前场景来切换画面,当前场景被释放。这是切换场景时最常用的方法。
voID CCDirector::replaceScene(CCScene *pScene){    CCAssert(m_pRunningScene,"Use runWithScene: instead to start the director");    CCAssert(pScene != NulL,"the scene should not be null");    unsigned int index = m_pobScenesStack->count();    m_bSendCleanupToScene = true;    m_pobScenesStack->replaceObjectAtIndex(index - 1,pScene);    m_pNextScene = pScene;}

popScene() 释放当前场景,再从代码执行场景中d出栈顶的场景,并将其设置为当前运行场景。如果栈为空,直接结束应用。和PushScene结对使用
voID CCDirector::popScene(voID){    CCAssert(m_pRunningScene != NulL,"running scene should not null");    m_pobScenesStack->removeLastObject();    unsigned int c = m_pobScenesStack->count();    if (c == 0)    {        end();    }    else    {        m_bSendCleanupToScene = true;        m_pNextScene = (CCScene*)m_pobScenesStack->objectAtIndex(c - 1);    }}

end() 释放和终止执行场景,同时退出应用
voID CCDirector::end(){    m_bPurgeDirecotorInNextLoop = true;}
pause() 暂停当前运行场景中的所有计时器和动作,场景仍然会显示在屏幕上
voID CCDirector::pause(voID){    if (m_bPaused)    {        return;    }    m_doldAnimationInterval = m_dAnimationInterval;    // when paused,don't consume cpu    setAnimationInterval(1 / 4.0);    m_bPaused = true;}

resume () 恢复当前运行场景的所有计时器和动作,场景仍然会显示在屏幕上
voID CCDirector::resume(voID){    if (! m_bPaused)    {        return;    }    setAnimationInterval(m_doldAnimationInterval);    if (CCTime::gettimeofdayCocos2d(m_pLastUpdate,NulL) != 0)    {        cclOG("cocos2d: Director: Error in gettimeofday");    }    m_bPaused = false;    m_fDeltaTime = 0;}

同时场景是层的容器,包含了所有需要显示的游戏元素。通常,当我们需要完成一个场景时候,会创建一个Scene的子类,并在子类中实现我们需要的功能。比如,我们可以在子类的初始化中载入游戏资源,为场景添加层,启动音乐播放等等。

层(Layer)

Layer是处理玩家事件响应的Node子类。与场景不同,层通常包含的是直接在屏幕上呈现的内容,并且可以接受用户的输入事件,包括触摸,加速度计和键盘输入等。我们需要在层中加入精灵,文本标签或者其他游戏元素,并设置游戏元素的属性,比如位置,方向和大小;设置游戏元素的动作等。通常,层中的对象功能类似,耦合较紧,与层中游戏内容相关的逻辑代码也编写在层中,在组织好层后,只需要把层按照顺序添加到场景中就可以显示出来了。要向场景添加层,我们可以使用addChild方法。

addChild( Nodechild ) addChild( Nodechild,int zOrder ) addChild( Node *child,int zOrder,int tag )

其中,Child参数就是节点。对于场景而言,通常我们添加的节点就是层。先添加的层会被置于后添加的层之下。如果需要为它们指定先后次序,可以使用不同的zOrder值。tag是元素的标识号码,如果为子节点设置了tag值,就可以在它的父节点中利用tag值就可以找到它了。层可以包含任何Node作为子节点,包括Sprites(精灵),Labels(标签),甚至其他的Layer对象。

class CC_DLL cclayer : public CCNode,public CCtouchDelegate,public CCAccelerometerDelegate,public CCKeypadDelegate/* "add" logic MUST only be on this method* If a class want's to extend the 'addChild' behavior it only needs* to overrIDe this method*/voID CCNode::addChild(CCNode *child,int tag){        CCAssert( child != NulL,"Argument must be non-nil");    CCAssert( child->m_pParent == NulL,"child already added. It can't be added again");    if( ! m_pChildren )    {        this->childrenAlloc();    }    this->insertChild(child,zOrder);    child->m_nTag = tag;    child->setParent(this);    child->setorderOfArrival(s_globalOrderOfArrivaL++);    if( m_bRunning )    {        child->onEnter();        child->onEnterTransitionDIDFinish();    }}voID CCNode::addChild(CCNode *child,int zOrder){    CCAssert( child != NulL,"Argument must be non-nil");    this->addChild(child,zOrder,child->m_nTag);}voID CCNode::addChild(CCNode *child){    CCAssert( child != NulL,child->m_nZOrder,child->m_nTag);}


上图所示的图片中,叫做HelloWorldScene的场景中有三个不同层,在layer3层上又有上个不同的精灵。下面是一个创建三个不同层的例子:

    cccolor4B tmpcolor1 = {0,128,255};    auto layer = cclayercolor::create(tmpcolor1);    layer->setContentSize(CCSizeMake(120,80));    layer->setposition(CCPoint(50,50));    addChild(layer,10);        cccolor4B tmpcolor2 = {128,255};    auto layer1 = cclayercolor::create(tmpcolor2);    layer1->setContentSize(CCSizeMake(120,80));    layer1->setposition(CCPoint(100,80));    addChild(layer1,20);        cccolor4B tmpcolor3 = {128,255};    auto layer2 = cclayercolor::create(tmpcolor3);    layer2->setContentSize(CCSizeMake(120,80));    layer2->setposition(CCPoint(150,110));    addChild(layer2,30);



精灵

Cocos2d中的精灵和其他游戏引擎中的精灵相似,它可以移动,旋转,缩放,执行动画,并接受其他转换。Cocos2dx的Sprite由Texure,frame和animation组成,由openes负责渲染。主要的类关系如下:


简单过程可描述为:使用Texture2D加载图片,可以用Texture2D生成对应的SpriteFrame(精灵帧),将SpriteFrame添加到Animation生成动画数据,用Animation生成Animate(就是最终的动画动作),最后用Sprite执行这个动作。

a.Sprite可以看成是某一时刻,一个2d的图片的一个剪辑部分

b.frame由texture和一个矩形(quad)组成

c.texture代表一个可以被绘制的2维的纹理

d.imgae对应硬盘中不同类型的图片,例如jpg,png,tga等.它知道如何从文件中读取不同类型的图片,生成缓冲数据,供texture使用

e.CCAnimation由一系列的frame组成,类似于电影的胶片集合

f.CCAnimate,动画action,实现在指定时间内在sprite上播放指定的动画(CCAnimation)

创建精灵的几种方式:

直接创建:
 auto sprite = CCSprite::create("HelloWorld.png");    this->addChild(sprite,0);
使用纹理来创建精灵
  auto sprite1 = CCSprite::createWithTexture(CCTextureCache::sharedTextureCache()->addImage("HelloWorld.png"));    this->addChild(sprite1,serif; Font-size:14px; line-height:25px">        使用精灵帧来创建精灵
auto sprite2=CCSprite::createWithSpriteFramename("HelloWorld.png");    this->addChild(sprite2,0);

在Cocos2dx中实现精灵显示的基本过程如下:

   //创建Scene    auto scene = CCScene::create();    //创建层    auto layer = AccelerometerTest::create();    //把层加入场景中    scene->addChild(layer);    //创建一个精灵    auto sprite = CCSprite::create("HelloWorld.png");    //把精灵加到层里    layer->addChild(sprite,0);


CCSprite* CCSprite::create(const char *pszfilename){    CCSprite *pobSprite = new CCSprite();    if (pobSprite && pobSprite->initWithfile(pszfilename))    {        pobSprite->autorelease();        return pobSprite;    }    CC_SAFE_DELETE(pobSprite);    return NulL;}bool CCSprite::initWithfile(const char *pszfilename){    CCAssert(pszfilename != NulL,"InvalID filename for sprite");    CCTexture2D *pTexture = CCTextureCache::sharedTextureCache()->addImage(pszfilename);    if (pTexture)    {        CCRect rect = CCRectZero;        rect.size = pTexture->getContentSize();        return initWithTexture(pTexture,rect);    }    // don't release here.    // when load texture Failed,it's better to get a "transparent" sprite than a crashed program    // this->release();     return false;}CCSprite* CCSprite::createWithSpriteFramename(const char *pszSpriteFramename){    CCSpriteFrame *pFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByname(pszSpriteFramename);    #if COCOS2D_DEBUG > 0    char msg[256] = {0};    sprintf(msg,"InvalID spriteFramename: %s",pszSpriteFramename);    CCAssert(pFrame != NulL,msg);#endif        return createWithSpriteFrame(pFrame);}CCSprite* CCSprite::createWithSpriteFrame(CCSpriteFrame *pSpriteFrame){    CCSprite *pobSprite = new CCSprite();    if (pSpriteFrame && pobSprite && pobSprite->initWithSpriteFrame(pSpriteFrame))    {        pobSprite->autorelease();        return pobSprite;    }    CC_SAFE_DELETE(pobSprite);    return NulL;}
总结

以上是内存溢出为你收集整理的cocos2d-x 基础概念介绍--导演 场景 层 精灵全部内容,希望文章能够帮你解决cocos2d-x 基础概念介绍--导演 场景 层 精灵所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1008832.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存