首页 > 代码库 > Cocos2d-x 系列五之三大特效

Cocos2d-x 系列五之三大特效

1.场景切换
新建一个类ImageScene

#ifndef IMAGESCENE_H
#define    IMAGESCENE_H
#include <iostream>
#include <cocos2d.h>

USING_NS_CC;

class ImageScene : public Layer {
public:

    virtual bool init() {
        Sprite *s = Sprite::create("HelloWorld.jpg");
        Size size = Director::getInstance()->getVisibleSize();
        s->setPosition(Point(size.width / 2, size.height / 2));
        addChild(s);
        return true;
    };

    static Scene* createScene() {
        Scene *s = Scene::create();
        ImageScene *layer = ImageScene::create();
        s->addChild(layer);
        return s;
    };

    CREATE_FUNC(ImageScene);
private:
};

#endif    /* IMAGESCENE_H */

在最初始的scene中添加一个labelTTF,并且点击它的时候切换到下一个场景(ImageScene)

bool HelloWorld::init() {
    //////////////////////////////
    // 1. super init first
    if (!Layer::init()) {
        return false;
    }
    Size size = Director::getInstance()->getVisibleSize();

    LabelTTF *label = LabelTTF::create("Show Next Scene", "Courier", 36);
    addChild(label);
    label->setPosition(Point(size.width / 2, size.height / 2));
    EventListenerTouchOneByOne *listener = EventListenerTouchOneByOne::create(); //
    listener->onTouchBegan = [label, size](Touch* t, Event * e) { //
        Point p = t->getLocation();
        p -= Point(size.width / 2, size.height / 2);
        if (label->getBoundingBox().containsPoint(p)) {
            log("change scene");
            Director::getInstance()->replaceScene(ImageScene::createScene());
        }
        return false;
    };
    Director::getInstance()->getEventDispatcher()
            ->addEventListenerWithSceneGraphPriority(listener, label);// 为label添加监听
    return true;
}

2.场景动画效果

往往在场景切换的时候,都需要添加一些动画,使看起来不是那么突然;

下面是一个场景切换动画效果例子,只需要将上面例子中的 Director::getInstance()->replaceScene(ImageScene::createScene()); 改为如下代码即可场景切换时添加一个动画;

Director::getInstance()->replaceScene(TransitionFadeBL::create(1, ImageScene::createScene())); // 1表示动画时长为1s

其它的场景效果可通过Api查看具体使用,在此不再一一说明;

3.cocos2d-x中的动作
>>1.动作
如果想要改变某一个node的位置,这就需要用到cocos2d-x中的动作Action了

label->runAction(MoveTo::create(1, Point(100, 100))); // 移动到(100,100),1表示动作时长1s

上面的方法是MoveTo,表示移动到某一个点,当然,也可以移动一段距离,对应的类就是MoveBy;
在cocos2d-x中,动作可以反转,下面看一句代码:

label->runAction(MoveBy::create(1, Point(50, 50))->reverse());

上面的代码,如果没有reverse,就表示向右上角移动(50,50)的距离,但是添加了reverse之后,动作就变成向左下角移动(50,50);

>>2.动作重复

    label->runAction(Repeat::create(RotateBy::create(1,180),4));// 动作重复4次
    label->runAction(RepeatForever::create(RotateBy::create(1,180)));// 动作一直重复

>>3.混合动作

auto actions = Spawn::create(MoveBy::create(1, Point(100, 100)), RotateBy::create(1, 360), NULL);
label->runAction(actions);        

混合动作的关键就是使用一个Spawn,将多个动作包装起来,一并执行;

>>4.序列动作

auto actions = Sequence::create(MoveBy::create(1, Point(100, 100)), RotateBy::create(1, 360), NULL);
label->runAction(actions);

序列动作和混合动作的区别就是把Spawn换成Sequence,把动作添加到一个序列里边按顺序执行;

>>5.动作侦听

在一个动作执行完毕后,往往都会进行一些附加的其它操作,如同android里面的动画侦听一样;

            auto actions = Sequence::create(
                    MoveBy::create(1, Point(100, 100)),
                    RotateBy::create(1, 360),
                    CallFunc::create([]() {
                        log("Action complete");
                    })
            , NULL); //
            label->runAction(actions);

通过在创建action的时候,传入一个动作完成的侦听函数,即可实现动作的侦听;该函数返回值为void,无参数;
CallFunc * CallFunc::create(const std::function<void()> &func)

在cocos2d-x中,已经封装好了很多的动作,在实际的使用中,可以根据这些动作来进行组合出更炫的动作;


 
4.帧动画

    auto cache = SpriteFrameCache::getInstance();// 获取一个帧动画缓存实例
    cache->addSpriteFramesWithFile("anim.plist");// 从文件中添加一个帧动画
    char name[15];
    memset(name, 0, 15);//
    Vector<SpriteFrame*> vec;//
    for (int i = 0; i < 20; i++) {
        sprintf(name, "anim%04d", i);//
        vec.pushBack(cache->getSpriteFrameByName(name));
    }

    Animation *anim = Animation::createWithSpriteFrames(vec, 0.1f); // 根据SpriteFrame*集合 创建一个动画;
    Animate *animate = Animate::create(anim); // 从动画中创建一个Animate Action;
    
    auto sprite = Sprite::create();
    addChild(sprite);
    sprite->setPosition(200, 200);
    sprite->runAction(RepeatForever::create(animate));