• cocos2dx 3.1从零学习(五)——动画


             动画是游戏中最重要的表现部分,本篇仅仅是初步学习大部分动画的用法。没有什么原理性的东西,可是样例有非常多,假设有不熟的地方要练一下。 特别是Spawn和Sequence的组合使用,什么时候使用Spawn,什么使用使用Sequence,怎么在它们之间相互嵌套对方。用光你的脑细胞尽力的去折磨这几个函数吧!

    做出尽可能多的绚丽的组合!

    动画方法

    动画的方法都在Node中,它的子类包含Layer、Sprite、MenuItem等。
    runAction 启动动画
    stopAction 停止动画
    stopActionByTag 依据tag停止动画
    ……

    动画原理

    创建好动作animation,在须要运行动作的地方运行runAction来对其加入动画。
    动画原理暂不做深入研究,后面做项目完好。


    经常使用动画

    Fade(In, Out)
    Move(To,By)
    Jump(To,By)

    eg:
    使某个精灵随机移动到屏幕上的某个点(注意均速运动)
    游戏中有二级跳,怎样实现

    Blink 闪烁
    Sequence 组合序列。动作依次运行,注意參数以NULL结尾。
    DelayTime 延时运行

    eg:
    设计一动画序列,平移200后。延时1秒后再分4次跳回。


    Rotate(To,By)环绕锚点(AnchorPoint)旋转
    Scale(To,By)缩放动画,s为放大缩小比例
    Spawn组合并行动画,动作同一时候运行。注意參数以NULL结尾

    eg:
    设计一动画。使背景旋转放大后充满屏幕
    设计一动画序列,向前旋转移动300像素后,平移100,然后再跳跃100.

    动画回调

    CallFunc  与sequence组合使用
    CallFuncN

    eg:
    4个精灵在中心位置先后移动到屏幕的4个角。
    //4个精灵在中⼼位置先后移动到屏幕的4个⾓
    void SecondaryJump:: FourSprites (cocos2d :: Ref * ref )
    {
        auto act = Sequence :: create( MoveTo ::create (1, Point(10, 10)), CallFuncN ::create ([=]( Node * node ){
            sp5 ->runAction ( Sequence:: create (MoveTo :: create(1, Point (10, 630)), CallFuncN :: create([=]( Node * node ){
                sp6 ->runAction ( Sequence:: create (MoveTo :: create(1, Point (950, 630)), CallFuncN :: create([=]( Node * node ){
                    sp7 ->runAction ( Sequence:: create (MoveTo :: create(1, Point (950, 10)), nullptr ));
                }), nullptr ));
            }), nullptr ));
        }), nullptr );
        sp4-> runAction (act );
    }


    动画回调加音效
         //动画回调
        auto callFunc = CallFuncN :: create([=]( Node * node )
        {
            node ->setVisible ( false);
        });
    
        auto act = Sequence :: create( Spawn ::create ( RotateTo:: create (2, 720), MoveBy :: create(2, Point (100, 0)), nullptr ), 
            MoveBy ::create (1, Point(100, 0)), JumpBy ::create (0.2f, Point(0, 0), 100, 1),  callFunc ,
            CallFuncN ::create ([=]( Node * node ){   
                   CocosDenshion :: SimpleAudioEngine:: sharedEngine ()->playBackgroundMusic ( "music/game_music.wav", true );   }),
            nullptr );
    
        sp2-> runAction (act );


    其它动画

    循环动画

    Repeat、RpeatForever
    //实现一个菜单button的抖动。 像那种输入账号password错误后。输入框抖动报错。
    在MenuItem的回调函数中这样写,事实上就是  左下 左上 右上 右下高速反复移动六次:
    void SecondaryJump:: Jump (cocos2d :: Ref * ref )
    {
        MenuItemFont * item = (MenuItemFont *) ref;
        auto repeatAct = Repeat :: create( Sequence ::create ( MoveBy:: create (0.01f, Point (3, 3)), MoveBy ::create (0.01f, Point(-3, -3)), MoveBy ::create (0.01f, Point(3, -3)), MoveBy ::create (0.01f, Point(-3, 3)), nullptr ), 6);
        item-> runAction (repeatAct );
    }

    帧动画Animate

    贝塞尔曲线

    void FrameAnimation:: Morning_0623 (cocos2d :: Ref * ref )
    {
        auto animation = Animation :: create();
        for ( int i = 2; i <= 6; i ++)
        {
            String fileName = StringUtils:: format ("coc/characters_lowres/%d.0.png" , i);
            animation ->addSpriteFrameWithFileName ( fileName. getCString ());
    
        }
        animation-> setDelayPerUnit (0.05f);
        animation-> setLoops (-1);
        auto animate = Animate :: create( animation );
    
        auto pArr = PointArray :: create(5);
        pArr-> addControlPoint (Point (100, 0));
        pArr-> addControlPoint (Point (100, 200));
        pArr-> addControlPoint (Point (300,200));
        pArr-> addControlPoint (Point (300, 400));
        auto move = CardinalSplineBy :: create(5, pArr , 1);
        auto act = Spawn :: create( animate , move , nullptr);
    
        ccBezierConfig bezierCon ;
        bezierCon. controlPoint_1 =CCPointMake (200, 150); //控制点1
        bezierCon. controlPoint_2 =CCPointMake (200, 160); //控制点2
        bezierCon. endPosition =CCPointMake (540, 100); // 结束位置
        sp-> runAction (Spawn :: create( act , BezierBy :: create(3, bezierCon ), nullptr ));
    }

    eg:
          屏幕上有10个精灵随机移动,精灵有对应的随机血量,相碰后血量少的精灵消失。最后仅仅剩下最后一个精灵。(考虑精灵封装成Enemy类)
          代码分析:我的代码中SpriteHW、SpriteHWT、AnimationHW这三个类。这道题的难度在于精灵碰撞检測后的删除。详细的能够參考AnimationHW的update。

    使用C++自身的vector,没有在遍历的时候进行删除,而是标记删除。

    在检測碰撞完成后再遍历一次vector对标记删除的元素进行删除。

          关于精灵随机位置的问题,使用rand会有每次执行随机数都一样的问题。这里给它加入一个随机种子。仅仅要在init()里面加入一句srand((unsigned)time(NULL));就可以每次随机不一样的数字。





    如今cocos2dx还没支持中文,我还没有找到好的unicode等转码的好的开源码,能力有限不想自己写搞得代码非常乱,囧。


    代码SVN同步地址(假设哪天没有了,见谅,可能不续费了):https://www.svnchina.com/svn/lanou


  • 相关阅读:
    结对编程项目作业3
    团队编程项目作业1-成员简介及分工
    团队编程项目作业1-需求分析
    结对编程项目作业1
    20171123-构建之法:现代软件工程-阅读笔记
    课后作业-阅读任务-阅读提问-4
    软件工程课程总结
    结对编程项目五子棋-结对项目总结
    课后作业-阅读任务-阅读笔记-1
    结对编程项目作业3
  • 原文地址:https://www.cnblogs.com/lytwajue/p/6729452.html
Copyright © 2020-2023  润新知