带冷却的菜单按钮完美封装。
下面是用到的两个图片:蓝色的是按钮,灰色的是冷却的蒙板效果。
按钮有三个状态:未点击,冷却中,不可点击。见图:
当然,数字不算在呢,还有图片好丑。好吧,好不专业。最讨厌不专业的了。
我们要做的是继承cocos2d提供的精灵菜单按钮项(CCMenuItemSprite),对它进行效果的添加。
首先我们要了解CCMenuItemSprite的使用:
//纹理缓存
CCTextureCache * textureCache = [CCTextureCache sharedTextureCache];
//未选择状态
CCSprite *normal = [CCSprite spriteWithTexture:[textureCache textureForKey:@"tool.png"]];
//选择状态
CCSprite *selected = [CCSprite spriteWithTexture:[textureCache textureForKey:@"tool.png"]];
//不可选择状态(可为空)
CCSprite *disabled = [CCSprite spriteWithTexture:[textureCache textureForKey:@"tool.png"]];
//精灵菜单项
CCMenuItemSprite *tool = [CCMenuItemSprite itemWithNormalSprite:normal selectedSprite:selected disabledSprite:disabled target:self selector:@selector(toolCallback)];
//菜单添加菜单项
CCMenu *menu = [CCMenu menuWithItems:tool, nil];
//菜单坐标为原点 这样菜单项就可以根据屏幕坐标设置位置
[menu setPosition:CGPointZero];
[self addChild:menu];
为什么不直接加载图片,难道你不觉得在游戏开始的时候把图片一次性加载到缓存里,会使游戏更加流畅,这也是为什么我们使用CCMenuItemSprite的原因。还有上述代码设置的用来响应按钮的回调函数:
-(void) toolCallback
{
//按钮的功能
}
以上是CCMenuItemSprite的使用,当然我们的封装也要这样的使用。网上有个博文对按钮的封装把响应按钮的回调函数写在了按钮类里,这就使封装毫无意义,添加一个按钮,就再写一个类?好不专业有没有。
首先声明部分:
#import <Foundation/Foundation.h>
#import "cocos2d.h"
@interface MYMenuItemSprite : CCMenuItemSprite {
//蒙板精灵
CCSprite *_becloundsSprite;
//冷却进度条
CCProgressTimer* _progressSprite;
//冷却时间
ccTime _time;
//是否正在冷却中
BOOL isCool;
}
//按钮图片 蒙板图片 冷却时间 当前layer 当前layer里的响应按钮函数
+(id)initMenuItemSprite:(CCSprite *)normalSprite becloudsSprite:(CCSprite *) becloundsSprite duration:(ccTime)time target:(id)target selector:(SEL)selector;
-(id)initMenuItemSprite:(CCSprite *)normalSprite becloudsSprite:(CCSprite *) becloundsSprite duration:(ccTime)time target:(id)target selector:(SEL)selector;
//冷却效果
-(void)coolingEffect;
//冷却完成后
-(void)progressCallback;
//按钮是否可用(和父类的只是有点像)
-(void)setEnabled:(BOOL) is;
@end
我们自己的冷却按钮也是按钮,继承自CCMenuItemSprite,对它进行功能的扩充。
下面是实现部分:
#import "MYMenuItemSprite.h"
@implementation MYMenuItemSprite
+(id)initMenuItemSprite:(CCSprite *)normalSprite becloudsSprite:(CCSprite *) becloundsSprite duration:(ccTime)time target:(id)target selector:(SEL)selector
{
//返回一个可以自动释放的对象
return [[[self alloc] initMenuItemSprite:normalSprite becloudsSprite:becloundsSprite duration:time target:target selector:selector] autorelease];
}
//自己的构造
-(id)initMenuItemSprite:(CCSprite *)normalSprite becloudsSprite:(CCSprite *) becloundsSprite duration:(ccTime)time target:(id)target selector:(SEL)selector
{
//未选择和已选择图片相同
CCSprite *sprite = [CCSprite spriteWithTexture:normalSprite.texture];
//父类的构造
self = [super initWithNormalSprite:normalSprite selectedSprite:sprite disabledSprite:nil target:target selector:selector];
//新的构造
if(self)
{
//蒙板精灵
_becloundsSprite = [CCSprite spriteWithTexture:becloundsSprite.texture];
_becloundsSprite.visible = NO;
//包含菜单的layer,包含蒙板精灵,在菜单项之上
[target addChild:_becloundsSprite z:2];
//冷却精灵,即按钮图片
CCSprite *sprite2 = [CCSprite spriteWithTexture:normalSprite.texture];
_progressSprite = [CCProgressTimer progressWithSprite:sprite2];
//包含菜单的layer,包含冷却精灵,在蒙版之上
[target addChild:_progressSprite z:3];
//冷却时间
_time = time;
}
return self;
}
-(void)dealloc
{
[super dealloc];
}
// 向父类的方法添加蒙板精灵的定位
-(void)setPosition:(CGPoint)position
{
[super setPosition:position];
_becloundsSprite.position = position;
[_progressSprite setPosition: position];
}
//父类的按钮点击后的回调函数
-(void) selected
{
[super selected];
}
//父类的离开按钮的回调函数
-(void) unselected
{
[super unselected];
//点击按钮后 播放冷却效果
[self coolingEffect];
}
//父类的回调函数
-(void) activate
{
//执行相应本按钮的回调函数
[super activate];
//回调函数执行后 按钮不可按状态
self.isEnabled = NO;
}
//冷却效果
-(void)coolingEffect
{
//冷却效果
CCActionInterval *action = [CCProgressTo actionWithDuration:_time percent:100];
CCCallFunc *callFunc = [CCCallFunc actionWithTarget:self selector:@selector(progressCallback)];
CCSequence *seq = [CCSequence actions:action, callFunc, nil];
[_progressSprite runAction:seq];
//蒙板可见
_becloundsSprite.visible = YES;
//冷却状态中
isCool = YES;
}
-(void)progressCallback
{
if (isCool) {
isCool = NO;
}else{
//若已提前结束冷却状态,则直接返回
return;
}
//冷却完毕 激活按钮
self.isEnabled = YES;
//蒙板不可见
_becloundsSprite.visible = NO;
}
//设置当前按钮是否可用
-(void)setEnabled:(BOOL) is
{
//冷却的时候不可进入可用状态,冷却的时候设置为不可用,可直接冷却完成
if(is){
if(!isCool){
self.isEnabled = YES;
_progressSprite.visible = YES;
_becloundsSprite.visible = NO;
}
}else
{
isCool = NO;
self.isEnabled = NO;
_progressSprite.visible = NO;
_becloundsSprite.visible = YES;
}
}
@end
有一点需要注意,我们传进去的回调函数对象即target:只能是当前添加菜单的CCNode,因为它需要绘制我们的蒙板图片,当然,平时的时候我们也都这样写。只是这里只能这样写。如果也非要传递一个非CCNode对象也可以,自己修改一下,添加一个参数,把添加菜单的CCNode传递进去。比如构造函数的末尾添加:scene:(CCNode*)scene
最后是对自己的冷却按钮项的使用:
{
CCTextureCache * textureCache = [CCTextureCache sharedTextureCache];
//蒙板图片
CCSprite *tool_b = [CCSprite spriteWithTexture:[textureCache textureForKey:@"tool_b.png"]];
CCSprite *normal = [CCSprite spriteWithTexture:[textureCache textureForKey: @"tool.png"]];
//自己的冷却菜单按钮项
MYMenuItemSprite *tool = [MYMenuItemSprite initMenuItemSprite:normal becloudsSprite:tool_b duration:1.1 target:self selector:@selector(toolMenuCallback)];
//设置冷却菜单项的位置
[tool setPosition:ccp(0,0)];
menu = [CCMenu menuWithItems:tool, nil];
[menu setPosition:CGPointZero];
[self addChild:menu z:1];
}
-(void) toolMenuCallback
{
//按钮的功能
}
和CCMenuItemSprite一样的使用是不是很激动。完美的封装到此结束,你可以根据自己的需求对他进行修改和内容的添加。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。