源码:git@github.com:baidang201/ARPG_Zhaoyun.git
/////////////////////////////////////////////////////////////////搬运
转载请注明出处http://www.jb51.cc/article/p-hdyrdsld-kh.html
本篇要讲讲怎么自定义按钮类,并通过这个按钮类的对像来控制精灵的攻击。在看本篇之前最好先看看上一篇
Cocos2d-x虚拟摇杆控制精灵上下左右运动----之游戏开发《赵云要格斗》(1),要素材和项目代码的把邮箱留下吧,因为这个项目还没弄完,我一直在改。
精灵的攻击也是一个动画,只不过,这个动画只播放一次,相当于在界面上加一个按钮,然后你点一次按钮,精灵就播放一次动画。这里之所以自定义按钮类是为了后头方便能添加多个按钮来实现英雄不同的攻击方式。以及技能冷却等。
cocos2d-x版本:2.2.5
工程环境:windows7+VS2010
打开方式:将工程放在cocos2d-x安装目录下的project文件夹下用VS打开目录
一、自定义按钮类
二、精灵攻击动画和结束判断
三、自定义按钮控制精灵
四、移植总结
一、自定义按钮类
按钮可以用COCOS2D-X自带的,想着方便一点,我就自己封装了一个按钮类MyControlButton,在里面添加一个//按钮控件变量ControlButton* controlBtn;并对其添加相应的回调事件即可实现我们自己封装的按钮类
#ifndef __ControlButton_H__
#define __ControlButton_H__
#include "cocos2d.h"
#include "cocos-ext.h"
#include "ui/UIScale9Sprite.h"
USING_NS_CC;
USING_NS_CC_EXT;
//用于标识当前按钮的状态
typedef enum{
touch_begin,
touch_down,
touch_up,
}tagForTouch;
class MyControlButton :public CCNode
{
public:
MyControlButton();
~MyControlButton();
CREATE_FUNC(MyControlButton);
//创建按钮,其中name_png为按钮的背景图片,button_title为按钮图片上要显示的文字,num为文字的透明度0-100,0为透明
void CreateButton(const char* name_png,const char* button_title="0",unsigned int num=0);
//绑写按钮事件
void BindButtonEven();
/* 当鼠标处于按下并曾经点中按钮时,则触发一次 */
void touchDownAction(Ref* pSender, Control::EventType event);
/* 当鼠标处于按下并曾经点中按钮的状态下,鼠标进入按钮范围,则触发一次 */
void touchDragEnter(Ref* pSender, Control::EventType event);
/* 当鼠标处于按下并曾经点中按钮的状态下,鼠标离开按钮范围,则触发一次 */
void touchDragExit(Ref* pSender, Control::EventType event);
/* 当鼠标处于按下并曾经点中按钮的状态下,鼠标进入按钮范围,则触发,只要达到条件,就不断触发 */
void touchDragInside(Ref* pSender, Control::EventType event);
/* 当鼠标处于按下并曾经点中按钮的状态下,鼠标离开按钮范围,则触发,只要达到条件,就不断触发 */
void touchDragOutside(Ref* pSender, Control::EventType event);
/* 当鼠标处于按下并曾经点中按钮的状态下,鼠标松开且在按钮范围内,则触发一次 */
void touchUpInside(Ref* pSender, Control::EventType event);
/* 当鼠标处于按下并曾经点中按钮的状态下,鼠标松开且在按钮范围外,则触发一次 */
void touchUpOutside(Ref* pSender, Control::EventType event);
/* 暂时没有发现能用鼠标触发这个事件的操作,看了注释,应该是由其它事件中断按钮事件而触发的 */
void touchCancel(Ref* pSender, Control::EventType event);
//是否按下按钮
bool isTouch;
private:
//按钮控件变量
ControlButton* controlBtn;
};
#endif
ControlButton.cpp文件
#include "ControlButton.h"
MyControlButton::MyControlButton():controlBtn(NULL),isTouch(false)
{
}
MyControlButton::~MyControlButton()
{
}
void MyControlButton::CreateButton(const char* name_png,const char* button_title,unsigned int num)
{
//得到按钮图片的大小
Scale9Sprite* btn = Scale9Sprite::create(name_png);
CCLOG("%f",btn->getContentSize().width);
CCLOG("%f",btn->getContentSize().height);
int png_height=static_cast<int>(btn->getContentSize().height);
int png_width=static_cast<int>( btn->getContentSize().width);
// btn->autorelease();
//要显示的图片大小
CCRect rect = CCRectMake(0,0,png_width,png_height); //图片的大小
CCRect rectInsets = CCRectMake(1,1,1); //left,right,width,height
//按钮标题,Marker Felt为字体类型,png_height为字体高度
CCLabelTTF *title = CCLabelTTF::create(button_title, "Marker Felt",png_height-10);
title->setOpacity(num);//设置可见度
//正常状态下的按钮图片
Scale9Sprite *btnNormal = Scale9Sprite::create(name_png,rect,rectInsets);
//创建按钮
controlBtn = ControlButton::create(title, btnNormal);
this->addChild(controlBtn);
//绑定事件
BindButtonEven();
}
void MyControlButton::BindButtonEven()
{
if(!controlBtn)
return;
controlBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(MyControlButton::touchDownAction),Control::EventType::TOUCH_DOWN);
controlBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(MyControlButton::touchDragEnter),Control::EventType::DRAG_ENTER);
controlBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(MyControlButton::touchDragExit),Control::EventType::DRAG_EXIT);
controlBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(MyControlButton::touchDragInside),Control::EventType::DRAG_INSIDE);
controlBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(MyControlButton::touchDragOutside),Control::EventType::DRAG_OUTSIDE);
controlBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(MyControlButton::touchUpInside),Control::EventType::TOUCH_UP_INSIDE);
controlBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(MyControlButton::touchUpOutside),Control::EventType::TOUCH_UP_OUTSIDE);
controlBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(MyControlButton::touchCancel),Control::EventType::TOUCH_CANCEL);
}
/* 当鼠标处于按下并曾经点中按钮时,则触发一次 */
void MyControlButton::touchDownAction(Ref* pSender, Control::EventType event)
{
isTouch=true;
}
/* 当鼠标处于按下并曾经点中按钮的状态下,鼠标进入按钮范围,则触发一次 */
void MyControlButton::touchDragEnter(Ref* pSender, Control::EventType event)
{
}
/* 当鼠标处于按下并曾经点中按钮的状态下,鼠标离开按钮范围,则触发一次 */
void MyControlButton::touchDragExit(Ref* pSender, Control::EventType event)
{
}
/* 当鼠标处于按下并曾经点中按钮的状态下,鼠标进入按钮范围,则触发,只要达到条件,就不断触发 */
void MyControlButton::touchDragInside(Ref* pSender, Control::EventType event)
{
}
/* 当鼠标处于按下并曾经点中按钮的状态下,鼠标离开按钮范围,则触发,只要达到条件,就不断触发 */
void MyControlButton::touchDragOutside(Ref* pSender, Control::EventType event)
{
}
/* 当鼠标处于按下并曾经点中按钮的状态下,鼠标松开且在按钮范围内,则触发一次 */
void MyControlButton::touchUpInside(Ref* pSender, Control::EventType event)
{
isTouch=false;
}
/* 当鼠标处于按下并曾经点中按钮的状态下,鼠标松开且在按钮范围外,则触发一次 */
void MyControlButton::touchUpOutside(Ref* pSender, Control::EventType event)
{
}
/* 暂时没有发现能用鼠标触发这个事件的操作,看了注释,应该是由其它事件中断按钮事件而触发的 */
void MyControlButton::touchCancel(Ref* pSender, Control::EventType event)
{
}
.cpp中保留了一些按钮的事件,如果后头有需要或者你有什么需要可以直接拿去改,十分方便。
使用方法:
在要用到的地方加头文件#include "ControlButton.h"
定义成员变量: ControlButton* btn;//按钮控件变量
在bool HelloWorld::init()函数里添加:
- //添加攻击按钮
- btn=ControlButton::create();
- btn->CreateButton("bt.png");
- btn->setPosition(ccp(visibleSize.width-50,50));
- this->addChild(btn,2);
@H_301_118@
@H_301_118@
二、精灵攻击动画和结束判断
void AttackAnimation(const char *name_plist,const char *name_png,const char *name_each,const unsigned int num,bool run_directon);
//攻击动画结束
void AttackEnd();
@H_301_118@
@H_301_118@
-
void Hero::AttackAnimation(const char *name_plist,const char *name_png,const char *name_each,const unsigned int num,bool run_directon)
{
if(IsAttack)
return;
//将图片加载到精灵帧缓存池
m_frameCache=CCSpriteFrameCache::sharedSpriteFrameCache();
m_frameCache->addSpriteFramesWithFile(name_plist,name_png);
frameArray = Vector<CCSpriteFrame*>();
unsigned int i;
for(i=1;i<=num;i++)
{
CCSpriteFrame* frame=m_frameCache->spriteFrameByName(CCString::createWithFormat("%s%d.png",name_each,i)->getCString());
frameArray.pushBack(frame);
}
//使用列表创建动画对象
CCAnimation* animation=CCAnimation::createWithSpriteFrames(frameArray);
if(HeroDirecton!=run_directon)
{ HeroDirecton=run_directon;
}
animation->setLoops(1);//表示循环播放次
animation->setDelayPerUnit(0.1f);//每两张图片的时间隔,图片数目越少,间隔最小就越小
//将动画包装成一个动作
CCAnimate* act=CCAnimate::create(animation);
//创建回调动作,攻击结束后调用AttackEnd()
CCCallFunc* callFunc=CCCallFunc::create(this,callfunc_selector(Hero::AttackEnd));
//创建连续动作
CCActionInterval* attackact=CCSequence::create(act,callFunc,NULL);
IsAttack=true;
m_HeroSprite->runAction(attackact);
}
void Hero::AttackEnd()
{
//恢复精灵原来的初始化贴图
this->removeChild(m_HeroSprite,true);//把原来的精灵删除掉
m_HeroSprite=CCSprite::create(Hero_name);//恢复精灵原来的贴图样子
m_HeroSprite->setFlipX(HeroDirecton);
this->addChild(m_HeroSprite);
IsAttack=false;
}
上面的创建连续动作是本次的关键点,在每次攻击动画AttackAnimation(...)结束后,它就会调用AttackEnd(),从而我们就可以知道是否在攻击动画了。 @H_301_118@
@H_301_118@
三、自定义按钮控制精灵
@H_301_118@
hero->AttackAnimation("attack1_animation.plist","attack1_animation.png","attack_",6,rocker->rocketRun);
@H_301_118@
四 移植总结
1 类型移植
CCObject* =》Ref*
CCControlEvent =》Control::EventType
CCControlEventTouchDown=> Control::EventType::TOUCH_DOWN CCControlEventTouchDragEnter=> Control::EventType::DRAG_ENTER CCControlEventTouchDragExit=> Control::EventType::DRAG_EXIT CCControlEventTouchDragInside=> Control::EventType::DRAG_INSIDE CCControlEventTouchDragOutside=> Control::EventType::DRAG_OUTSIDE CCControlEventTouchUpInside=> Control::EventType::TOUCH_UP_INSIDE CCControlEventTouchUpOutside=> Control::EventType::TOUCH_UP_OUTSIDE CCControlEventTouchCancel=> Control::EventType::TOUCH_CANCEL