cocos2dx学习之路----第十三篇(动作类初探)

这一篇,我们就来谈谈关于cocos2dx中动作类相关的问题。

cocos2dx之所以成为主流的2D游戏引擎之一,离不开的是它拥有了强大的动作类。为什么这么说呢?不妨先来看看在cocos2dx3.9这一版本中它的动作类的类结构图吧(因为条件限制,所以只能显示这么大,大家可以先把它下载另存为.jpg文件,然后放大即可清楚查看):

在这张图中我们可以很清楚的看到这一个动作(Action)类的复杂之处。
好,现在就直接进入正题吧。 其实关于cocos2dx中的动作类,如果一个个讲我觉得也没什么必要。但是,至少我们要清楚它大概的轮廓或者说是关系。从图中我们可以获取得到,Action类是继承Ref类和Clonable类的。 Ref类是一个引用类型的类,它与内存管理相关,这个我们后面会谈及。而Clonable是一个可以复制的类。也就是说它的子类或是子类的子类都是可以克隆复制的。这样一来,我们便会清楚,所有的Action类都可以克隆复制的。 而这一篇,我会简单的讲讲关于它的子类相关的实例。
第一个是Follow类,它的作用是对摄像头进行目标的锁定,这样,目标一旦即将离开摄像机视野之时,那么,摄像机会锁定目标随之移动,从而达到目标保持在视野范围内。
第二个是Speed类,它主要和ActionInterval类相关(关于这个类,我们下面会谈及)。使用这个类,可以对移动的目标进行速度的调整。
第三个是FiniteTimeAction类,它又派生出了两个子类。ActionInterval类和ActionInstant类。关于这两个类,其实可以顾名思义的看出,一个是有间隔时间的动作,一个是即时的动作。所以,刚刚说的Speed类就是需要有一个有时间间隔的动作,这样才能对移动的速度进行调整。
OK,现在就来看下关于Follow和Speed这两个类吧,关于有时间的动作,后面再来选择性的进行分析,毕竟动作类很多。不过,对于上面的类的例子,我选择了一个有时间的MoveBy类进行结合。
好,话不多说,先看实现的例子效果:

以上就是关于这两个类的简单实例演示。代码如下:
RunActionTest.h:

#ifndef __RUN_ACTION_TEST_H__
#define __RUN_ACTION_TEST_H__

#include"cocos2d.h"

using namespace cocos2d;

#define winSize Director::getInstance()->getWinSize()

enum TEST_LAYER{
    TEST_NONE,
    TEST_ACTION_SPEED_1,
    TEST_ACTION_F0LLOW_2
};

static int currentSceneIndex = 0;

class ActionSpeedTestLayer : public Layer {
public:
    const std::string title(){ return "ActionSpeedTestLayer Test"; }
    virtual bool init();
    CREATE_FUNC(ActionSpeedTestLayer);
};

class ActionFollowTestLayer : public Layer {
public:
    const std::string title(){ return "ActionFollowTestLayer Test"; }
    virtual bool init();
    CREATE_FUNC(ActionFollowTestLayer);
};

class ActionScene :public Scene{
public:
    virtual bool init();
    CREATE_FUNC(ActionScene);

    virtual void restartCallback(Ref *sender);
    virtual void nextCallback(Ref *sender);
    virtual void priorCallback(Ref *sender);
protected:
    MenuItemImage *priorItem, *restartItem, *nextItem;
};
#endif

RunActionTest.cpp:

#include"RunActionTest.h"

bool ActionSpeedTestLayer::init(){
    if (!Layer::init()){
        return false;
    }
    //Add title
    auto title = Label::createWithSystemFont(this->title(), "", 25);
    this->addChild(title);
    title->setPosition(Vec2(
        winSize.width / 2,
        winSize.height - title->getContentSize().height / 2));

    //Set current scene index
    currentSceneIndex = 1;

    //Action
    auto actionSpeed1 = Speed::create(MoveBy::create(5.0f, Vec3(300, 0, 0)), 0.5f);
    auto actionSpeed2 = Speed::create(MoveBy::create(5.0f, Vec3(300, 0, 0)), 1.0f);
    auto actionSpeed3 = Speed::create(MoveBy::create(5.0f, Vec3(300, 0, 0)), 1.5f);
    //Icon sprite
    auto IconSprite1 = Sprite::create("Icon.png");
    IconSprite1->setPosition(Vec2(IconSprite1->getContentSize().width/2, winSize.height * 3 / 4));
    addChild(IconSprite1);
    IconSprite1->runAction(actionSpeed1);

    auto IconSprite2 = Sprite::create("Icon.png");
    IconSprite2->setPosition(Vec2(IconSprite1->getContentSize().width / 2, winSize.height * 1 / 2));
    addChild(IconSprite2);
    IconSprite2->runAction(actionSpeed2);

    auto IconSprite3 = Sprite::create("Icon.png");
    IconSprite3->setPosition(Vec2(IconSprite1->getContentSize().width / 2, winSize.height * 1 / 4));
    addChild(IconSprite3);
    IconSprite3->runAction(actionSpeed3);

    return true;
}

bool ActionFollowTestLayer::init(){
    if (!Layer::init()){
        return false;
    }
    //Add title
    auto title = Label::createWithSystemFont(this->title(), "", 25);
    this->addChild(title);
    title->setPosition(Vec2(
        winSize.width / 2,
        winSize.height - title->getContentSize().height / 2));

    //Set current scene index
    currentSceneIndex = 2;

    //Draw Line
    auto drawNode = DrawNode::create();
    drawNode->drawLine(Vec2(0, winSize.height / 2), Vec2(winSize.width * 2, winSize.height / 2), Color4F::RED);
    drawNode->drawLine(Vec2(0, winSize.height), Vec2(winSize.width * 2, winSize.height), Color4F::RED);
    drawNode->drawLine(Vec2(winSize.width / 2, 0), Vec2(winSize.width / 2, winSize.height * 2), Color4F::RED);
    drawNode->drawLine(Vec2(winSize.width, 0), Vec2(winSize.width, winSize.height * 2), Color4F::RED);
    this->addChild(drawNode);

    //Icon sprite
    auto IconSprite = Sprite::create("Icon.png");
    IconSprite->setPosition(Vec2::ZERO);
    addChild(IconSprite);
    IconSprite->runAction(MoveBy::create(2.0f,Vec3(winSize.width,winSize.height,0)));

    this->runAction(Follow::create(IconSprite, Rect(0, 0, winSize.width * 2, winSize.height * 2)));
    return true;
}


bool ActionScene::init(){
    if (!Scene::init()){
        return false;
    }
    //Set current search path for resource
    FileUtils::getInstance()->addSearchPath("RunctionRes/");

    priorItem = MenuItemImage::create("p1.png", "p2.png",
        CC_CALLBACK_1(ActionScene::priorCallback, this));
    priorItem->setPosition(Vec2(
        -winSize.width / 2 + priorItem->getContentSize().width/2,
        -winSize.height / 2 + priorItem->getContentSize().height / 2));

    nextItem = MenuItemImage::create("n1.png", "n2.png",
        CC_CALLBACK_1(ActionScene::nextCallback, this));
    nextItem->setPosition(Vec2(
        winSize.width / 2 - priorItem->getContentSize().width / 2,
        -winSize.height / 2 + priorItem->getContentSize().height / 2));

    restartItem = MenuItemImage::create("r1.png", "r2.png",
        CC_CALLBACK_1(ActionScene::restartCallback, this));
    restartItem->setPosition(Vec2(
        0,-winSize.height / 2 + priorItem->getContentSize().height / 2));


    auto menu = Menu::create(priorItem, nextItem, restartItem,NULL);
    this->addChild(menu);

    auto test_for_speed_layer = ActionSpeedTestLayer::create();
    this->addChild(test_for_speed_layer);
    test_for_speed_layer->setTag(TEST_ACTION_SPEED_1);


    return true;
}

void ActionScene::restartCallback(Ref *sender){
    switch (currentSceneIndex){
    case 1:
        if (this->getChildByTag(TEST_ACTION_SPEED_1)){
            this->removeChildByTag(TEST_ACTION_SPEED_1);

            auto test_for_speed_layer = ActionSpeedTestLayer::create();
            this->addChild(test_for_speed_layer);
            test_for_speed_layer->setTag(TEST_ACTION_SPEED_1);
        }
        break;
    case 2:
        if (this->getChildByTag(TEST_ACTION_F0LLOW_2)){
            this->removeChildByTag(TEST_ACTION_F0LLOW_2);

            auto test_for_follow_layer = ActionFollowTestLayer::create();
            this->addChild(test_for_follow_layer);
            test_for_follow_layer->setTag(TEST_ACTION_F0LLOW_2);
        }
        break;
    default:
        break;
    }
}

void ActionScene::nextCallback(Ref *sender){
    switch (currentSceneIndex){
    case 1:
        if (this->getChildByTag(TEST_ACTION_SPEED_1)){
            this->removeChildByTag(TEST_ACTION_SPEED_1);

            auto test_for_follow_layer = ActionFollowTestLayer::create();
            this->addChild(test_for_follow_layer);
            test_for_follow_layer->setTag(TEST_ACTION_F0LLOW_2);
        }
        break;
    default:
        break;
    }
}

void ActionScene::priorCallback(Ref *sender){
    switch (currentSceneIndex){
    case 2:
        if (this->getChildByTag(TEST_ACTION_F0LLOW_2)){
            this->removeChildByTag(TEST_ACTION_F0LLOW_2);

            auto test_for_speed_layer = ActionSpeedTestLayer::create();
            this->addChild(test_for_speed_layer);
            test_for_speed_layer->setTag(TEST_ACTION_SPEED_1);
        }
        break;
    default:
        break;
    }
}

好了,具体的就不再分析了。相信大家都能够看得明白,如果有错误或是不懂得可以指出哦~

你可能感兴趣的:(cocos2dx,游戏引擎,动作类)