zoukankan      html  css  js  c++  java
  • Cocos2d-x手机游戏开发中-组合动作

    动作往往不是单一,而是复杂的组合。

    我们能够依照一定的次序将上述基本动作组合起来,形成连贯的一套组合动作。

    组合动作包含以下几类:顺序、并列、有限次数反复、无限次数反复、反动作和动画。动画我们会在下一节介绍。本节我们重点顺序、并列、有限次数反复、无限次数反复和反动

    以下我们通过一个实例介绍一下组合动作的使用,这个实比例如以下图所看到的。下图是一个操作菜单场景,选择菜单能够进入到下图动作场景,在下图动作场景中点击Gobutton能够运行我们选择的动作效果,点击Backbutton能够返回到菜单场景。


    以下我们再看看详细的程序代码,首先看一下看HelloWorldScene.h文件。它的代码例如以下:

    #ifndef __HELLOWORLD_SCENE_H__
    #define __HELLOWORLD_SCENE_H__
     
    #include "cocos2d.h"
    #include "MyActionScene.h"                                                                                                                ①
     
    typedef enum {                                                                                                                             ②
       kSequence = 100,
       kSpawn,
       kRepeate,
       kRepeatForever1,
       kReverse
    } ActionTypes;                                                                                                                             ③
     
    class HelloWorld : public cocos2d::Layer
    {
    public:
     
       static cocos2d::Scene* createScene();
       virtual bool init(); 
       
       void OnClickMenu(cocos2d::Ref* pSender);                                                                              ④
       
       CREATE_FUNC(HelloWorld);
    };
     
    #endif // __HELLOWORLD_SCENE_H__

    上述代码是中第①行是引入头文件MyActionScene.h。

    第②~③是定义个枚举类型ActionTypes,枚举类型ActionTypes中定义了5个常量。这5个常量相应5个菜单项。第④行声明了一个函数,用来在选择不同菜单时候的回调。

    在上诉代码大家比較熟悉了,我们这里就不再介绍了。以下我们再看看下一个场景MyActionScene,它的MyActionScene.h代码例如以下:

    #ifndef __MYACTION_SCENE_H__
    #define __MYACTION_SCENE_H__
     
    #include "cocos2d.h"
    #include "HelloWorldScene.h"
     
    class MyAction : public cocos2d::Layer
    {
       cocos2d::Sprite *sprite;
     
    public:
       
        staticcocos2d::Scene* createScene();
       virtual bool init();
       CREATE_FUNC(MyAction);
       
       void goMenu(cocos2d::Ref* pSender);
       void backMenu(cocos2d::Ref* pSender);
     
            voidOnSequence(cocos2d::Ref* pSender);                                                                              ①
       void OnSpawn(cocos2d::Ref* pSender);
       void OnRepeat(cocos2d::Ref* pSender);
       void OnReverse(cocos2d::Ref* pSender);
       void OnRepeatForever(cocos2d::Ref* pSender);                                                            ②
    };
     
    #endif // __MYACTION_SCENE_H__

    在.h文件里第①~②行代码是声明了5个用于菜单选择的回调函数。

    MyActionScene的实现代码MyActionScene.ccp文件,当中点击Gobutton时候调用的函数MyAction::goMenu代码例如以下:

    void MyAction::goMenu(Ref* pSender)
    {  
        log("Tag= %i",this->getTag());
       switch (this->getTag()) {
             casekSequence:
                 this->OnSequence(pSender);
                 break;
             casekSpawn:
                this->OnSpawn(pSender);
                 break;
             casekRepeate:
                this->OnRepeat(pSender);
                 break;
             casekRepeatForever1:
                this->OnRepeatForever(pSender);
                 break;
             case kReverse:
                 this->OnReverse(pSender);
                 break;
           default:
                 break;
        }
    }

    我们在这个函数中依据选择菜单不同调用不同的函数。

    MyActionScene.ccp中MyActionLayer::OnSequence代码例如以下:
    void MyAction::OnSequence(Ref* pSender)
    {
       Size size = Director::getInstance()->getVisibleSize();
            Pointp = Point(size.width/2, 200);
     
       FiniteTimeAction* ac0 =(FiniteTimeAction*)sprite->runAction(Place::create(p));                  ①
       FiniteTimeAction* ac1 = (FiniteTimeAction*)sprite->runAction(
                                                    MoveTo::create(2,Point(size.width- 130, size.height - 200)));         ②
       FiniteTimeAction* ac2 = (FiniteTimeAction*)sprite->runAction(
                                                    JumpBy::create(2,Point(8, 8),6, 3));                                          ③
       FiniteTimeAction* ac3 =(FiniteTimeAction*)sprite->runAction(Blink::create(2,3));                ④
       FiniteTimeAction* ac4 = (FiniteTimeAction*)sprite->runAction(
                                                    TintBy::create(0.5,0,255,255));                                                   ⑤
       
          sprite->runAction(Sequence::create(ac0,ac1, ac2, ac3, ac4, ac0, NULL));                             ⑥
     
    }

    上述代码实现了顺序动作演示。当中主要使用的类是Sequence。Sequence是派生于ActionInterval属性间隔动作。Sequence作用就是顺序排列若干个动作,然后按先后次序逐个运行。代码⑥行运行Sequence,Sequence的create函数须要动作数组。

    代码第①行创建Place动作。因为Sequence的create函数须要FiniteTimeAction类型的动作,因此须要将表达式sprite->runAction(Place::create(p))强制转换为FiniteTimeAction*类型。

    相似的代码第②~⑤行都须要强制类型转换。第②行代码是创建MoveTo动作,第③行代码是创建JumpBy动作。第④行代码是创建Blink动作。第⑤行代码是创建TintBy动作。

    MyActionScene.ccp中MyActionLayer::OnSpawn,这个函数是在演示并列动作时候调用的函数,它的代码例如以下:

    void MyAction::OnSpawn(Ref* pSender)
    {
       Size size = Director::getInstance()->getVisibleSize();
        Pointp = Point(size.width/2, 200);
       
       sprite->setRotation(0);                                                                                                          ①
            sprite->setPosition(p);                                                                                                        ②
       
       FiniteTimeAction* ac1 = (FiniteTimeAction*)sprite->runAction(
                               MoveTo::create(2,Point(size.width- 100, size.height - 100)));                     ③
       FiniteTimeAction* ac2 =(FiniteTimeAction*)sprite->runAction(RotateTo::create(2, 40));       ④
       
       sprite->runAction(Spawn::create(ac1,ac2,NULL));                                                                      ⑤
       
    }

    上述代码实现了并列动作演示,当中主要使用的类是Spawn类也从ActionInterval继承而来,该类作用就是同一时候并列运行若干个动作。但要求动作都必须 是能够同一时候运行的。比方:移动式翻转、改变色、改变大小等。第⑤行代码sprite->runAction(Spawn::create(ac1,ac2,NULL))运行并列动作,create函数的动作类型数组。

    第①行代码sprite->setRotation(0)设置精灵旋转角度保持原来状态。第②行代码sprite->setPosition(p)是又一次设置精灵位置。

    第③行代码创建MoveTo动作。第④行代码创建RotateTo动作。

    MyActionScene.ccp中MyActionLayer::OnRepeat,这个函数是在演示反复动作时候调用的函数。它的代码例如以下:

    void MyAction::OnRepeat(Ref* pSender)
    {
       Size size = Director::getInstance()->getVisibleSize();
        Pointp = Point(size.width/2, 200);
       
       sprite->setRotation(0);
            sprite->setPosition(p);
       
       FiniteTimeAction* ac1 = (FiniteTimeAction*)sprite->runAction(
                               MoveTo::create(2,Point(size.width- 100, size.height - 100)));                     ①
       FiniteTimeAction* ac2 = (FiniteTimeAction*)sprite->runAction(
                               JumpBy::create(2,Point(10,10), 20,5));                                                          ②
       FiniteTimeAction* ac3 = (FiniteTimeAction*)sprite->runAction(
                               JumpBy::create(2,Point(-10,-10),20,3));                                                         ③
       
       ActionInterval* seq = Sequence::create(ac1, ac2, ac3, NULL);                                         ④
       
       sprite->runAction(Repeat::create(seq,3));                                                                                    ⑤
       
    }

    上述代码实现了反复动作演示,当中主要使用的类是Repeat类也从ActionInterval继承而来。第①行代码是创建MoveTo动作。第②行代码是创建JumpBy动作。

    第③行代码是创建JumpBy动作。

    第④行代码是创建顺序动作对象seq,seq的类型为ActionInterval*或FiniteTimeAction*。第⑤行代码sprite->runAction(Repeat::create(seq,3)) 反复运行顺序动作3次,create函数參数的类型是FiniteTimeAction。

    MyActionScene.ccp中MyActionLayer::OnRepeatForever。这个函数是在演示无限反复动作时候调用的函数,它的代码例如以下:

    void MyAction::OnRepeatForever(Ref*pSender)
    {
       Size size = Director::getInstance()->getVisibleSize();
             Point p = Point(size.width/2, 500);
       
       sprite->setRotation(0);
            sprite->setPosition(p);
       
            ccBezierConfigbezier;                                                                                                         ①
       bezier.controlPoint_1 = Point(0, size.height/2);
            bezier.controlPoint_2= Point(10, -size.height/2);
            bezier.endPosition= Point(10,20);                                                                                  ②
       FiniteTimeAction* ac1 =(FiniteTimeAction*)sprite->runAction(BezierBy::create(2,bezier));   ③
     
       FiniteTimeAction* ac2 = (FiniteTimeAction*)sprite->runAction(
                                    TintBy::create(0.5,0, 255, 255));                                                                           ④
       FiniteTimeAction* ac1Reverse = ((ActionInterval*)ac1)->reverse();                                          ⑤
       FiniteTimeAction* ac2Repeat = (FiniteTimeAction*)sprite->runAction(
                                    Repeat::create((ActionInterval*)ac2,4));                                                    ⑥
       
       FiniteTimeAction* ac3 = (FiniteTimeAction*)sprite->runAction(
                                           Spawn::create(ac1,ac2Repeat,NULL));                                                ⑦
       
       FiniteTimeAction* ac4 = (FiniteTimeAction*)sprite->runAction(
                                           Spawn::create(ac1Reverse,ac2Repeat,NULL));                                           ⑧
       
       ActionInterval* seq = Sequence::create(ac3, ac4, NULL);                                                 ⑨
       
       sprite->runAction(RepeatForever::create(seq));                                                                         ⑩
       
    }

    上述代码实现了反复动作演示。当中主要使用的类是RepeatForever,它也从ActionInterval继承而来。

    第⑩行代码sprite->runAction(RepeatForever::create(seq))是运行无限反复动作,create函数參数的类型是FiniteTimeAction。代码第①~②行是定义贝塞尔曲线控制点。第③行代码创建贝塞尔曲线动作BezierBy。第④行代码创建动作TintBy。第⑤行代码是创建BezierBy动作的反转动作。

    第⑥行代码是创建反复动作。

    第⑦和⑧行代码是创建并列动作。

    第⑨行代码是创建顺序动作。

    MyActionScene.ccp中MyActionLayer::OnReverse,这个函数是在演示反动作时候调用的函数,它的代码例如以下:

    void MyAction::OnReverse(Ref* pSender)
    {
       Size size = Director::getInstance()->getVisibleSize();
            Pointp = Point(size.width/2, 300);
       
       sprite->setRotation(0);
            sprite->setPosition(p);
       
       FiniteTimeAction* ac1 = (FiniteTimeAction*)sprite->runAction(
                                                    MoveBy::create(2,Point(40,60)));                                                        ①
       Action* ac2 = ac1->reverse();                                                                                               ②
     
       ActionInterval* seq = Sequence::create(ac1, ac2, NULL);                                                 ③
       
       sprite->runAction(Repeat::create(seq,2));                                                                                    ④
       
    }

    上述代码实现了反动作演示,支持顺序动作的反顺序动作。反顺序动作不是一个类,不是全部的动作类都支持反动作。XxxTo 类通常不支持反动作。XxxBy类通常支持。

    第①行代码是创建一个移动MoveBy动作。第②行代码调用ac1的reverse()函数运行反动作。第③行代码是创建顺序动作。

    第④行代码sprite->runAction(Repeat::create(seq,2))是运行反动作。


    很多其它内容请关注最新Cocos图书《Cocos2d-x实战 C++卷》
    本书交流讨论站点:http://www.cocoagame.net
    很多其它精彩视频课程请关注智捷课堂Cocos课程:http://v.51work6.com
    欢迎增加Cocos2d-x技术讨论群:257760386


    《Cocos2d-x实战 C++卷》现已上线,各大商店均已开售:

    京东:http://item.jd.com/11584534.html

    亚马逊:http://www.amazon.cn/Cocos2d-x%E5%AE%9E%E6%88%98-C-%E5%8D%B7-%E5%85%B3%E4%B8%9C%E5%8D%87/dp/B00PTYWTLU

    当当:http://product.dangdang.com/23606265.html

    互动出版网:http://product.china-pub.com/3770734

    《Cocos2d-x实战 C++卷》源代码及样章下载地址:

    源代码下载地址:http://51work6.com/forum.php?

    mod=viewthread&tid=1155&extra=page%3D1 

    样章下载地址:http://51work6.com/forum.php?mod=viewthread&tid=1157&extra=page%3D1

    欢迎关注智捷iOS课堂微信公共平台

  • 相关阅读:
    FLUSH TABLES WITH READ LOCK 锁全局
    第三届中国云计算用户大会笔记和心得
    第三届中国云计算用户大会笔记和心得
    报表或BI的价值在哪?
    ZooKeeper
    TypeError:First argument must be file descriptor
    org.eclipse.core.runtime.OperationCanceledException
    perl 安装 ZooKeeper模块
    2、Zookeeper集群搭建、命令行Client操作
    1、Zookeeper熟悉和用途综述
  • 原文地址:https://www.cnblogs.com/wzzkaifa/p/6811268.html
Copyright © 2011-2022 走看看