上一節課程中我們實作了攻擊判定,讓你的英雄可以殺死敵人。在這一課中,我們在控制(操作)層多添加一個待冷卻時間顯示的技能按鈕,實作釋放技能,給你的英雄添加大招。
開發環境
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類,來實作技能攻擊效果。如果技能太快了,找到他的動畫改改幀數。
受限于素材,相當的搓,可以稍稍改改這個代碼,從外部改善它。
我還是比較希望直接用原來的技能圖檔,通過改變這個圖檔的紋理(灰階,可見度)實作冷卻展示,而不是用新的圖檔。
本篇展示結束。下一篇我們添加一個暫停按鈕,實作暫停功能。