上一节课程中我们实现了攻击判定,让你的英雄可以杀死敌人。在这一课中,我们在控制(操作)层多添加一个待冷却时间显示的技能按钮,实现释放技能,给你的英雄添加大招。
开发环境
Win64 : vs2010
Cocos2d-x v3.4Final
TexturePackerGUI
MapEdit
代码
Operate
SkillButton
我们新建一个SkillButton
.h
#ifndef _SKILL_BUTTON_H_
#define _SKILL_BUTTON_H_
#include "cocos2d.h"
USING_NS_CC;
#include "Global.h"
class SkillButton : public Node
{
public:
SkillButton();
~SkillButton();
//CREATE_FUNC(SkillButton);
static SkillButton* create(const char* Nomal,const char* Click,const char* Mask,float CDTime);
static SkillButton* create(const char* Nomal,const char* Mask,float CDTime)
{return SkillButton::create(Nomal,Nomal,Mask,CDTime);};
static SkillButton* create(const char* Nomal,const char* Mask)
{return SkillButton::create(Nomal,Nomal,Mask,1.0f);};
static SkillButton* create(const char* Nomal,float CDTime)
{return SkillButton::create(Nomal,Nomal,Nomal,CDTime);};
static SkillButton* create(const char* Nomal)
{return SkillButton::create(Nomal,Nomal,Nomal,1.0f);};
CC_SYNTHESIZE(float,_cdtime,CDTime);
void ClickCallBack(Ref* obj);
void CoolDownCallBack(Node* node);
private:
bool init(const char* Nomal,const char* Click,const char* Mask,float CDTime);
private:
MenuItemImage* _ItemSkill; // 技能按钮
Sprite* _Mask; // 蒙板精灵,黑色半透明(这个是为了显示一个冷却计时效果)
ProgressTimer* _ProgressTimer; // 时间进度条精灵(360度旋转)
Label* _atLabel; // 显示冷却
float CdTime; // 冷却时间
void CoolDownReduce(float dt); //冷却时间显示定时器
};
#endif
通过实现creat重载来自定义输入的图片。后面调用的时候我只用指定2个参数,图片显示效果和CD时间实现调用。
.cpp
#include "SkillButton.h"
SkillButton::SkillButton():
_ItemSkill(NULL),
_Mask(NULL),
_cdtime(1.0f),
_ProgressTimer(NULL)
{
}
SkillButton::~SkillButton()
{
}
SkillButton* SkillButton::create(const char* Normal, const char* Click ,const char* Mask , float CDTime )
{
SkillButton* skillButton = new SkillButton();
if (skillButton && skillButton->init(Normal,Click,Mask,CDTime))
{
skillButton->autorelease();
return skillButton;
}
else
{
CC_SAFE_DELETE(skillButton);
return nullptr;
}
}
bool SkillButton::init(const char* Normal, const char* Click , const char* Mask , float CDTime )
{
bool ret = false;
do {
CC_BREAK_IF( !Node::init());
//断点宏啊,其实在本Demo中去掉没啥影响
CCAssert(Mask, "SkillButton::init Mask != NULL");
CCAssert(Normal, "SkillButton::init Normal != NULL");
CCAssert(Click, "SkillButton::init Click != NULL");
// Notice:添加child时要注意上下层
// 最下方是MenuItemImage 其次是蒙版图片 最上方是ProgressTimer
// 添加技能按钮
_ItemSkill = MenuItemImage::create(Normal, Click, CC_CALLBACK_1(SkillButton::ClickCallBack,this));
_ItemSkill->setPosition(Vec2::ZERO);
auto MenuSkill = Menu::create(_ItemSkill, NULL);
MenuSkill->setPosition(Vec2::ZERO);
addChild(MenuSkill, -100);
// 添加蒙版
if(Normal==Mask)
{
_Mask = Sprite::create();
_Mask->setTexture(Normal);
_Mask->setColor(Color3B(0,0,0));
_Mask->setOpacity(100);
}
else
{
_Mask = Sprite::create(Mask);
}
_Mask->setPosition(Vec2::ZERO);
_Mask->setVisible(false);
addChild(_Mask,0);
// 添加旋转进度条精灵,设置为顺时针扇形进度计时器
_ProgressTimer = ProgressTimer::create(Sprite::create(Normal));
_ProgressTimer->setType(ProgressTimer::Type::RADIAL);
_ProgressTimer->setPosition(Vec2::ZERO);
_ProgressTimer->setVisible(false);
addChild(_ProgressTimer, 100);
this->setCDTime(CDTime);
CdTime=CDTime;
_atLabel = Label::create();
_atLabel->setSystemFontSize(_Mask->getContentSize().width/3);
_atLabel->setColor(Color3B(0,0,0));
_atLabel->setPosition(Vec2::ZERO);
addChild(_atLabel,200);
_atLabel->setVisible(false);
ret = true;
} while(0);
return ret;
}
void SkillButton::ClickCallBack(Ref* obj)
{
// 设置技能按钮不可点击
_ItemSkill->setEnabled(false);
// 设置蒙版可见
_Mask->setVisible(true);
// 设置进度条可见
_ProgressTimer->setVisible(true);
//设置剩余时间可见
_atLabel->setVisible(true);
//开启定时器
this->schedule(schedule_selector(SkillButton::CoolDownReduce),0.1f);
//Hero释放技能A
global->hero->runChangeAttack();
//准备一个持续时间为CDTime秒,旋转360度*100% 的动画(逐渐覆盖半透模板形成冷却效果;这里进行计时冷却动画的实现和时间控制)
//ActionInterval持续动作是需要持续运行一段时间的动作。 它有一个启动时间和结束时间。结束时间由启动时间加上周期得出
ActionInterval* action_progress_to = Sequence::create(
ProgressTo::create(this->getCDTime(), 100),
NULL);
CallFunc* action_callback = CallFuncN::create(CC_CALLBACK_1(SkillButton::CoolDownCallBack,this));
_ProgressTimer->runAction(Sequence::create(action_progress_to, action_callback, NULL));
}
void SkillButton::CoolDownReduce(float dt)
{
_atLabel->setString(__String::createWithFormat("%.1f",CdTime-=0.1f)->getCString());
}
void SkillButton::CoolDownCallBack(Node* node)
{
// 按钮置为可用
_ItemSkill->setEnabled(true);
// 设置蒙板不可见
_Mask->setVisible(false);
// 进度条技能不可见
_ProgressTimer->setVisible(false);
_ProgressTimer->setPercentage(0);
//设置剩余时间不可见
_atLabel->setVisible(false);
CdTime=this->getCDTime();
//取消定时器
this->unschedule(schedule_selector(SkillButton::CoolDownReduce));
}
蒙版是当技能CD时显示的样子,可以自己指定一些图片显示:
当按下时,使这个技能按钮不可点击,然后显示一个Progress持续时间为CD,从0-100%顺时针旋转的进程;
技能冷却完毕时重新时它可点击,隐藏蒙版;
剩余时间显示通过定时器设置,当然最后别忘了取消;
然后将这个SkillButton添加入我们的控制层。不要忘了#include。
Operate
.cpp
auto skillA = SkillButton::create("SkillButton.png",3.0f);
skillA->setPosition(attackItem->getPosition()-Vec2(50,0));
this->addChild(skillA);
效果
结语
新建了一个SkillButton类,来实现技能攻击效果。如果技能太快了,找到他的动画改改帧数。
受限于素材,相当的搓,可以稍稍改改这个代码,从外部改善它。
我还是比较希望直接用原来的技能图片,通过改变这个图片的纹理(灰度,可见度)实现冷却展示,而不是用新的图片。
本篇展示结束。下一篇我们添加一个暂停按钮,实现暂停功能。