上一节课程中我们实现了攻击判定,让你的英雄可以杀死敌人。在这一课中,我们在控制(操作)层多添加一个待冷却时间显示的技能按钮,实现释放技能,给你的英雄添加大招。

开发环境

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);

效果


20150210115236683.gif

结语

       新建了一个SkillButton类,来实现技能攻击效果。如果技能太快了,找到他的动画改改帧数。

       受限于素材,相当的搓,可以稍稍改改这个代码,从外部改善它。

       我还是比较希望直接用原来的技能图片,通过改变这个图片的纹理(灰度,可见度)实现冷却展示,而不是用新的图片。

       本篇展示结束。下一篇我们添加一个暂停按钮,实现暂停功能。