Cocos2d-x 学习旅程 Day 1 – 基本概念

昨天搭建好了cocos2d-x的开发环境,今天开始正式学习。

有必先了解一些基本概念(好像拍电影啊):

导演(CCDirector):顾名思义,就是一个游戏的总指挥,负责把控全场,所有场景切换工作都由导演来执行。

场景(CCScene):场景是视觉元素的容器,我们把层,精灵,菜单都放在这个容器里。

层(CCLayer):层的概念想必大家已经接触过很多了,比如横版过关游戏中,就有好多层,人物移动,后面的背景也跟着移动,但是前面的任务栏,图标栏,技能栏都没有移动,就是因为他们在不同的层上

精灵(CCSprite):精灵就是演员啦,你的角色,你控制的飞机坦克小伙伴都是通过精灵的形式展示出来的,恩,NPC也是精灵。精灵就是一连串的动画构成的一个角色。

动作(Action):动作是通过改变图像的属性来使图像呈现出动态变化,比如缩放,旋转,位移等,精灵通过一系列的动作让你觉得它是活得。

通常导演负责各个场景的切换,一个场景里可以有多个层,每个层里可以有多个精灵,精灵又可以有很多动作,他们都是一对多的关系,如下图:

20130309101653227

下面我们先来创建一个导演,cocos2d-x已经为我们写好了一个导演的单例方法,导演是全局唯一的。

我们打开 AppDelegate.cpp,找到里面的applicationDidFinishLaunching方法

bool AppDelegate::applicationDidFinishLaunching() {
// initialize director
CCDirector* pDirector = CCDirector::sharedDirector();
CCEGLView* pEGLView = CCEGLView::sharedOpenGLView();

pDirector->setOpenGLView(pEGLView);

// turn on display FPS
pDirector->setDisplayStats(true);

// set FPS. the default value is 1.0/60 if you don't call this
pDirector->setAnimationInterval(1.0 / 60);

// create a scene. it's an autorelease object
CCScene *pScene = HelloWorld::scene();

// run
pDirector->runWithScene(pScene);

return true;
}

我们可以看到CCDirector::sharedDirector()返回一个CCDirector实例的指针,下次用到导演的时候直接调用这个方法就可以了。

接下来说一说创建场景:
我们看到上面的代码块中有这么一句:

CCScene *pScene = HelloWorld::scene();

其中HelloWorld是我们自己生成的类的名字,那这个 scene() 方法是做什么用的呢?
我们打开MyHelloWorld.cpp文件,可以看到如下代码:

CCScene* MyHelloWorld::scene()
{
	CCScene* ret = CCScene::create();
	CCLayer* layer = MyHelloWorld::create();
	ret->addChild(layer);
	return ret;
}

这个方法的意思是在方法里生成了一个空的CCScene对象(注意在Cocos2d-x中,创建新对象的方法基本上都是Class::create(),记住哦),然后创建了一个自己类的实例,通过addChild(CCLayer Object)添加到刚才创建的CCScene对象ret中,最后把这个对象的指针返回给调用者,为什么要这么写呢,为什么是返回一个CCScene而不是返回一个CCLayer?我自己的理解是,因为CCScene是一个容器,本身没有任何的内容,所以如果是由CCLayer的对象(MyHelloWorld继承自CCLayer)来负责填充这个CCScene并且返回给调用者,对于调用者来说更加的方便,不用每次都要自己建一个空的场景。

下面就说到重要的层(CCLayer)了,创建方法如下:
打开MyHelloWorld.h,我们可以看到MyHelloWorld直接继承自CCLayer,代码如下

class MyHelloWorld : public cocos2d::CCLayer
{
public:
    virtual bool init();  

    static cocos2d::CCScene* scene();

    void menuCloseCallback(CCObject* pSender);

    CREATE_FUNC(MyHelloWorld);
};

有没有发现什么问题,没有???好吧,我们看到上面代码中调用了MyHelloWorld::create();这个方法,可是它没有定义呀,这是怎么回事呢?秘密就在

CREATE_FUNC(MyHelloWorld)

中,这其实是一个宏,创建了一个静态的create()方法,返回一个新的MyHelloWorld对象,具体可以参考CREATE_FUNC宏的定义,用到了模板方法哦。
其中

void menuCloseCallback(CCObject* pSender);

是关闭按钮的回调函数,负责当用户单击了关闭按钮之后关闭窗口。
现在就剩下一个最重要的

virtual bool init()

方法了,
我们看看它的实现,打开MyHelloWorld.cpp,可以看到如下代码,我把每行的意思写在注释里了

bool HelloWorld::init()
{
    // 初始化父类
    if ( !CCLayer::init() )
    {
        return false;
    }

    // 得到当前窗口的大小
    CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
    // 坐标原点
    CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();

    // 添加一个叉叉图像的菜单按钮, 当用户单击的时候就退出
    CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
                                        "CloseNormal.png",
                                        "CloseSelected.png",
                                        this,
                                        menu_selector(HelloWorld::menuCloseCallback));   
    pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,
                                origin.y + pCloseItem->getContentSize().height/2));

    // 创建菜单对象,并把刚才的菜单按钮加进来
    CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
    pMenu->setPosition(CCPointZero);
    this->addChild(pMenu, 1);

    // 创建一个显示"Hello World"的标签    
    CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", 24);    
    pLabel->setPosition(ccp(origin.x + visibleSize.width/2,
                            origin.y + visibleSize.height - pLabel->getContentSize().height));

    // 把标签添加到当前层中
    this->addChild(pLabel, 1);

    // 创建以HelloWorld.png为样子的精灵
    CCSprite* pSprite = CCSprite::create("HelloWorld.png");
    pSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));

    this->addChild(pSprite, 0);

    return true;
}

创建精灵(CCSprite)的方法很简单,看上面的代码

 CCSprite* pSprite = CCSprite::create("HelloWorld.png");

这样就创建了一个精灵,图片HelloWorld.png在Resources文件夹下。
CCSprite有好多功能,可以放大、缩小、拉伸、压缩、旋转、改变颜色等等,我们可以运行code里自带的SpriteTest项目来对CCSprite能干的事情有个大概了解。

至于动作(Action)嘛,自动生成的例子里面,没有带,那我们就来自己添加一个好了,在上面的代码

this->addChild(pSprite, 0)

这一行下面加入如下代码,

CCMoveTo* moveto = CCMoveTo::create(0.9f, ccp(400,150));
pSprite->runAction(moveto);

再运行一遍,看,是不是画面动起来了,一个简单的移动Action就完成了,是不是很简单啊。
好了,今天先到这里吧。

博主开通了微信公众号,欢迎关注啦

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.