zoukankan      html  css  js  c++  java
  • Cocos2d-x 实现技能冷却效果

    CD动画,也就是技能冷却。

    介绍:技能冷却的效果跟魔兽世界中的技能冷却类似,功能如下:技能图标点击时会有按下效果,抬起后开始冷却计时,冷却计时技术后该图标才可以再次进行点击。
    实现:三层实现:
    最下方是CCMenuItemImage 按钮图片 -- normal
    中间是半透明模版图片 -- stencil
    最上方是CCProgressTimer 图片是最下图中较大的图片 -- click
    这是使用的图片资源(normal,click,stencil)
     
    动画原理:
    非冷却状态时只显示CCMenuItemImage,当冷却开始计时时,将按钮设为不可点击状态,同将半透明模板和进度条精灵设置为可见状态,并且进度条精灵开始进行旋转动作,旋转结束后在回调函数中将半透明模板和进度条精灵设为不可见,按钮重新设置为可点击状态。
     
    下面先看看原作者的实现方案:
     1 /** 
     2     实现技能冷却效果 
     3 
     4     Notice:添加child时要注意上下层关系
     5     最下方是按钮 其次是半透明的模版图片 最上方是CCProgressTimer进度条精灵
     6 */
     7 #ifndef _SKILLBUTTON_H_
     8 #define _SKILLBUTTON_H_
     9 #include <cocos2d.h>
    10 
    11 class SkillButton : public cocos2d::CCNode
    12 {
    13 public:
    14     SkillButton();
    15     virtual ~SkillButton();
    16 
    17     /** 创建一个SkillButton对象
    18         */
    19     static SkillButton* createSkillButton(float cdTime,
    20                                         const char* stencil_file_name, 
    21                                         const char* button_normal_name, 
    22                                         const char* button_click_name);
    23 
    24     /** CD时间设置
    25         */
    26     void    setCDTime(float time) { mCDTime = time; }
    27     float   getCDTime() const { return mCDTime; }
    28 
    29     /** 技能按钮点击回调 */
    30     void    skillClickCallBack(cocos2d::CCObject* obj);
    31 
    32     /** 技能冷却完毕回调*/
    33     void    skillCoolDownCallBack(cocos2d::CCNode* node);
    34 
    35 private:
    36 
    37     /** 初始化 */
    38     bool    init(float cdTime, const char* stencil_file_name, const char* button_normal_name, const char* button_click_name);
    39 
    40 private:
    41     cocos2d::CCMenuItemImage*   mItemSkill;     // 技能按钮
    42     cocos2d::CCMenu*            mMenuSkill;     // 技能按钮所在menu
    43     cocos2d::CCSprite*          mStencil;       // 蒙板精灵,黑色半透明(这个是为了显示一个冷却计时效果)
    44     cocos2d::CCProgressTimer*   mProgressTimer; // 时间进度条精灵(360度旋转)
    45     float                       mCDTime;          // CD时间
    46 };
    47 #endif
      1 #include "SkillButton.h"
      2 
      3 USING_NS_CC;
      4 
      5 SkillButton::SkillButton():
      6     mItemSkill(NULL),
      7     mMenuSkill(NULL),
      8     mStencil(NULL),
      9     mProgressTimer(NULL),
     10     mCDTime(1.f)
     11 {
     12 
     13 }
     14 
     15 SkillButton::~SkillButton()
     16 {
     17 
     18 }
     19 
     20 SkillButton* SkillButton::createSkillButton(float cdTime, const char* stencil_file_name, const char* button_normal_name, const char* button_click_name)
     21 {
     22     SkillButton* skillButton = new SkillButton();
     23     if (skillButton && skillButton->init(cdTime, stencil_file_name, button_normal_name, button_click_name))
     24     {
     25         skillButton->autorelease();
     26         return skillButton;
     27     }
     28     else
     29     {
     30         delete skillButton;
     31         skillButton = NULL;
     32     }
     33 
     34     return NULL;
     35 }
     36 
     37 bool SkillButton::init(float cdTime, const char* stencil_file_name, const char* button_normal_name, const char* button_click_name)
     38 {
     39     CCAssert(stencil_file_name, "SkillButton::init stencil_file_name != NULL");
     40     CCAssert(button_normal_name, "SkillButton::init button_normal_name != NULL");
     41     CCAssert(button_click_name, "SkillButton::init button_click_name != NULL");
     42 
     43     // Notice:添加child时要注意上下层
     44     // 最下方是CCMenuItemImage 其次是模版图片 最上方是CCProgressTimer
     45 
     46     // 添加技能按钮 下层
     47     mItemSkill = CCMenuItemImage::create(button_normal_name, button_click_name, this, menu_selector(SkillButton::skillClickCallBack));
     48     mItemSkill->setPosition(CCPointZero);
     49 
     50     mMenuSkill = CCMenu::create(mItemSkill, NULL);
     51     mMenuSkill->setPosition(CCPointZero);
     52     addChild(mMenuSkill, -100);
     53 
     54     // 添加阴影模版 中间层
     55     mStencil = CCSprite::create(stencil_file_name);
     56     mStencil->setPosition(CCPointZero);
     57     mStencil->setVisible(false);
     58     addChild(mStencil);
     59 
     60     // 添加旋转进度条精灵 上层
     61     CCSprite* progressSprite = CCSprite::create(button_normal_name);
     62     mProgressTimer = CCProgressTimer::create(progressSprite);
     63     mProgressTimer->setPosition(CCPointZero);
     64     mProgressTimer->setVisible(false);
     65     addChild(mProgressTimer, 100);
     66 
     67     mCDTime = cdTime;
     68     return true;
     69 }
     70 
     71 /** 技能按钮点击回调 */
     72 void SkillButton::skillClickCallBack(cocos2d::CCObject* obj)
     73 {
     74     // 冷却计时,即时状态技能按钮不可点击
     75     mItemSkill->setEnabled(false);
     76 
     77     // 模版可见
     78     mStencil->setVisible(true);
     79 
     80     // 设置精灵进度条为顺时针
     81     mProgressTimer->setVisible(true);
     82     mProgressTimer->setType(kCCProgressTimerTypeRadial);
     83 
     84     //准备一个旋转360度的动画(逐渐覆盖半透模板形成冷却效果;这里进行计时冷却动画的实现和时间控制)
     85     CCActionInterval* action_progress_to = CCProgressTo::create(mCDTime, 100);
     86     CCCallFunc* action_callback = CCCallFuncN::create(this, callfuncN_selector(SkillButton::skillCoolDownCallBack));
     87     mProgressTimer->runAction(CCSequence::create(action_progress_to, action_callback, NULL));
     88 }
     89 
     90 /** 技能冷却完成回调 */
     91 void SkillButton::skillCoolDownCallBack(CCNode* node)
     92 {
     93     // 设置蒙板不可见
     94     mStencil->setVisible(false);
     95 
     96     // 进度条技能不可见
     97     mProgressTimer->setVisible(false);
     98 
     99     // 按钮置为可用
    100     mItemSkill->setEnabled(true);
    101 }

    使用:(注意创建时其中的参数:第一个是冷却时间,其他都是图片)

    1 CCSize s = CCDirector::sharedDirector()->getWinSize();
    2     SkillButton* mSkillButton = SkillButton::createSkillButton(2.f, "stencil.png", "normal.png", "click.png");
    3     mSkillButton->setPosition(ccp(s.width/2, s.height/2));
    4     addChild(mSkillButton);

    技能效果:

    改进实现:我觉得其实这种实现方式有点麻烦,其实两层就可以实现了。

    两层实现:
    下层:CCMenuItemImage 按钮图片 -- normal
    上层:CCProgressTimer 图片是半透明模版图片 -- stencil
     
    实现过程:飞冷却状态下,只显示CCMenuItemImage,而上层的半透明图片是隐藏的。当实现冷却技能的效果时,下层的CCMenuItemImage设置为不可点击状态,而上层的半透明图片实现进度条的环形旋转,从360度顺时针减少到0度。

    下面给出改进版的实现
    只列出有变化的代码:

    1、关于 cocos2d::CCSprite*  mStencil; 这个精灵的所有代码都去掉
    2、修改实现文件中的函数有如下:
     1 bool SkillButton::init(float cdTime, const char* stencil_file_name, const char* button_normal_name, const char* button_click_name)
     2 {
     3     CCAssert(stencil_file_name, "SkillButton::init stencil_file_name != NULL");
     4     CCAssert(button_normal_name, "SkillButton::init button_normal_name != NULL");
     5     CCAssert(button_click_name, "SkillButton::init button_click_name != NULL");
     6     
     7     // 添加技能按钮 下层
     8     mItemSkill = CCMenuItemImage::create(button_normal_name, button_click_name, this, menu_selector(SkillButton::skillClickCallBack));
     9     mItemSkill->setPosition(CCPointZero);
    10     
    11     mMenuSkill = CCMenu::create(mItemSkill, NULL);
    12     mMenuSkill->setPosition(CCPointZero);
    13     addChild(mMenuSkill, -100);
    14     
    15     // 添加旋转进度条精灵---半阴影 上层
    16     CCSprite* progressSprite = CCSprite::create(stencil_file_name);
    17     mProgressTimer = CCProgressTimer::create(progressSprite);
    18     mProgressTimer->setPosition(CCPointZero);
    19     mProgressTimer->setVisible(false);
    20     addChild(mProgressTimer, 100);
    21     
    22     mCDTime = cdTime;
    23     return true;
    24 }
    25 
    26 /** 技能按钮点击回调 */
    27 void SkillButton::skillClickCallBack(cocos2d::CCObject* obj)
    28 {
    29     // 冷却计时,即时状态技能按钮不可点击
    30     mItemSkill->setEnabled(false);
    31     
    32     
    33     mProgressTimer->setVisible(true);
    34     mProgressTimer->setType(kCCProgressTimerTypeRadial);
    35     mProgressTimer->setReverseProgress(true); // 设置进度条为逆时针
    36 
    37     //准备一个旋转360度的动画(逐渐覆盖半透模板形成冷却效果;这里进行计时冷却动画的实现和时间控制)
    38     
    39     //注意这里冷却效果是从100%到0%顺时针变化的
    40     CCActionInterval* action_progress_from_to = CCProgressFromTo::create(mCDTime, 100, 0); 
    41     
    42     CCCallFunc* action_callback = CCCallFuncN::create(this, callfuncN_selector(SkillButton::skillCoolDownCallBack));
    43     mProgressTimer->runAction(CCSequence::create(action_progress_from_to, action_callback, NULL));
    44 }
    45 
    46 /** 技能冷却完成回调 */
    47 void SkillButton::skillCoolDownCallBack(CCNode* node)
    48 {
    49     // 进度条技能不可见
    50     mProgressTimer->setVisible(false);
    51     
    52     // 按钮置为可用
    53     mItemSkill->setEnabled(true);
    54 }

    ok,再次运行,效果是完全一致的。

    原文链接: http://blog.csdn.net/crayondeng/article/details/11265207

  • 相关阅读:
    并查集_贪心_求无向图最短连通路径_最小生成树(kruskal)
    01背包&&完全背包_顺序枚举和逆序枚举的问题_一维数组
    week7_简单题_C_水题_hdu_5578+F_贪心_hdu_5583
    计量经济学_大纲
    概率专题_概率/ 数学_基础题_ABEI
    动态规划_01背包_从Dijikstra和Floyd入手,彻底理解01背包
    动态规划_基础_最长公共子序列_多种方法_递归/dp
    动态规划_基础_分治思想_从归并排序到任意子区间序列求和_滑动窗口+递推
    分治思想_归并排序_各种写法和思路(待续)
    递归基础_整数划分类问题_ 多状态转移复杂递推
  • 原文地址:https://www.cnblogs.com/atong/p/3309755.html
Copyright © 2011-2022 走看看