cocos2d-x 3.2 扇形按钮

今天心血来潮做了个扇形按钮,想起android的扇形按钮那是非常的复杂,而cocos2d-x做起来却这么方便。

HelloWorld.h

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

class HelloWorld : public cocos2d::Layer
{
private:
	cocos2d::MenuItemSprite* menuItem;
	cocos2d::MenuItemSprite* menuItem1;
	cocos2d::MenuItemSprite* menuItem2;
	cocos2d::MenuItemSprite* menuItem3;
	cocos2d::MenuItemSprite* menuItem4;
	cocos2d::MenuItemSprite* menuItem5;
	cocos2d::Menu* menu;
	bool isShow;
public:
    // there's no 'id' in cpp, so we recommend returning the class instance pointer
    static cocos2d::Scene* createScene();

    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
    virtual bool init();  
    
    // implement the "static create()" method manually
    CREATE_FUNC(HelloWorld);

	void btnCallback(cocos2d::Ref* pSender);
	void btnCallback1(cocos2d::Ref* pSender);
	void btnCallback2(cocos2d::Ref* pSender);
	void btnCallback3(cocos2d::Ref* pSender);
	void btnCallback4(cocos2d::Ref* pSender);
	void btnCallback5(cocos2d::Ref* pSender);
	void enabledCallback(cocos2d::Ref* pSender);

	cocos2d::ActionInterval* spawnOut(cocos2d::Vec2 point, float duration);
	cocos2d::ActionInterval* spawnIn(float duration);
};

#endif // __HELLOWORLD_SCENE_H__



HelloWorld.cpp

#include "HelloWorldScene.h"

USING_NS_CC;

Scene* HelloWorld::createScene()
{
	// 'scene' is an autorelease object
	auto scene = Scene::create();

	// 'layer' is an autorelease object
	auto layer = HelloWorld::create();

	// add layer as a child to scene
	scene->addChild(layer);

	// return the scene
	return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
	//
	// 1. super init first
	if (!Layer::init())
	{
		return false;
	}

	isShow = false;

	SpriteFrameCache::getInstance()->addSpriteFramesWithFile("button.plist");

	menuItem = MenuItemSprite::create(
		Sprite::createWithSpriteFrameName("btn.png"),
		Sprite::createWithSpriteFrameName("btn.png"),
		CC_CALLBACK_1(HelloWorld::btnCallback, this)
		);
	//menuItem->setTag(1000);
	menuItem->setPosition(Vec2(200, 200));

	menuItem1 = MenuItemSprite::create(
		Sprite::createWithSpriteFrameName("btn1.png"),
		Sprite::createWithSpriteFrameName("btn1.png"),
		CC_CALLBACK_1(HelloWorld::btnCallback1, this)
		);
	//menuItem1->setTag(1001);
	//menuItem1->setRotation(-360);
	//menuItem1->setPosition(200, 400);
	menuItem1->setPosition(Vec2(200, 200));

	menuItem2 = MenuItemSprite::create(
		Sprite::createWithSpriteFrameName("btn2.png"),
		Sprite::createWithSpriteFrameName("btn2.png"),
		CC_CALLBACK_1(HelloWorld::btnCallback1, this)
		);
	//menuItem2->setTag(1002);
	//menuItem2->setPosition(270, 370);
	menuItem2->setPosition(Vec2(200, 200));

	menuItem3 = MenuItemSprite::create(
		Sprite::createWithSpriteFrameName("btn3.png"),
		Sprite::createWithSpriteFrameName("btn3.png"),
		CC_CALLBACK_1(HelloWorld::btnCallback1, this)
		);
	//menuItem3->setTag(1003);
	//menuItem3->setPosition(330, 330);
	menuItem3->setPosition(Vec2(200, 200));

	menuItem4 = MenuItemSprite::create(
		Sprite::createWithSpriteFrameName("btn4.png"),
		Sprite::createWithSpriteFrameName("btn4.png"),
		CC_CALLBACK_1(HelloWorld::btnCallback1, this)
		);
	//menuItem4->setTag(1004);
	//menuItem4->setPosition(370, 270);
	menuItem4->setPosition(Vec2(200, 200));

	menuItem5 = MenuItemSprite::create(
		Sprite::createWithSpriteFrameName("btn5.png"),
		Sprite::createWithSpriteFrameName("btn5.png"),
		CC_CALLBACK_1(HelloWorld::btnCallback1, this)
		);
	//menuItem5->setTag(1005);
	//menuItem5->setPosition(400, 200);
	menuItem5->setPosition(Vec2(200, 200));

	menu = Menu::create(menuItem1, menuItem2, menuItem3, menuItem4, menuItem5, menuItem, NULL);
	//mn->setTag(1100);
	menu->setPosition(Vec2::ZERO);
	this->addChild(menu, 10);


	return true;
}

void HelloWorld::btnCallback(Ref* pSender)
{
	FiniteTimeAction* acf = (FiniteTimeAction*)CallFuncN::create(CC_CALLBACK_1(HelloWorld::enabledCallback, this));
	if (isShow)
	{
		menuItem->runAction(RotateTo::create(0.3f, -720));
		menuItem1->runAction(HelloWorld::spawnIn(0.6f));
		menuItem2->runAction(HelloWorld::spawnIn(0.65f));
		menuItem3->runAction(HelloWorld::spawnIn(0.7f));
		menuItem4->runAction(HelloWorld::spawnIn(0.75f));
		//menuItem5->runAction(HelloWorld::spawnIn(0.8f));
		menuItem5->runAction(Sequence::create(HelloWorld::spawnIn(0.8f), acf, nullptr));
	}
	else
	{
		menuItem->runAction(RotateTo::create(0.3f, 720));
		menuItem1->runAction(HelloWorld::spawnOut(Vec2(200, 400), 0.6f));
		menuItem2->runAction(HelloWorld::spawnOut(Vec2(270, 370), 0.65f));
		menuItem3->runAction(HelloWorld::spawnOut(Vec2(330, 330), 0.7f));
		menuItem4->runAction(HelloWorld::spawnOut(Vec2(370, 270), 0.75f));
		//menuItem5->runAction(HelloWorld::spawnOut(Vec2(400, 200), 0.8f));
		menuItem5->runAction(Sequence::create(HelloWorld::spawnOut(Vec2(400, 200), 0.8f), acf, nullptr));
	}

	isShow = !isShow;
	menu->setEnabled(false);
}

ActionInterval* HelloWorld::spawnIn(float duration)
{
	ActionInterval* rotateTo = RotateTo::create(duration, -1080);
	auto move_ease_in = EaseBackIn::create(MoveTo::create(duration, Vec2(200, 200)));
	return Spawn::create(move_ease_in, rotateTo, nullptr);
}

ActionInterval* HelloWorld::spawnOut(Vec2 point, float duration)
{
	//auto delay = DelayTime::create(1);
	ActionInterval* rotateTo = RotateTo::create(duration, 1080);
	auto move_ease_out = EaseBackOut::create(MoveTo::create(duration, point));
	return Spawn::create(move_ease_out, rotateTo, nullptr);
}

void HelloWorld::btnCallback1(Ref* pSender)
{}
void HelloWorld::btnCallback2(Ref* pSender)
{}
void HelloWorld::btnCallback3(Ref* pSender)
{}
void HelloWorld::btnCallback4(Ref* pSender)
{}
void HelloWorld::btnCallback5(Ref* pSender)
{}
void HelloWorld::enabledCallback(Ref* pSender)
{
	menu->setEnabled(true);
}



回弹的效果主要参考了cpp-tests里的ActionsEaseTest.cpp

//------------------------------------------------------------------
//
// SpriteEaseBack
//
//------------------------------------------------------------------

void SpriteEaseBack::onEnter()
{
    EaseSpriteDemo::onEnter();
    
    auto move = MoveBy::create(3, Vec2(VisibleRect::right().x-130, 0));
    auto move_back = move->reverse();
    
    auto move_ease_in = EaseBackIn::create(move->clone());
    auto move_ease_in_back = move_ease_in->reverse();
    
    auto move_ease_out = EaseBackOut::create( move->clone());
    auto move_ease_out_back = move_ease_out->reverse();
    
    auto delay = DelayTime::create(0.25f);
    
    auto seq1 = Sequence::create(move, delay, move_back, delay->clone(), nullptr);
    auto seq2 = Sequence::create(move_ease_in, delay->clone(), move_ease_in_back, delay->clone(), nullptr);
    auto seq3 = Sequence::create(move_ease_out, delay->clone(), move_ease_out_back, delay->clone(), nullptr);
    
    _grossini->runAction(RepeatForever::create(seq1));
    _tamara->runAction(RepeatForever::create(seq2));
    _kathia->runAction(RepeatForever::create(seq3));    
}

增加了控制连续点击按钮导致动作不能执行完的问题。

最初是用了一个变量来控制,可能哪里没设置好导致控制不完美,感谢cocoachina的版主指出使用menu->setEnabled(false);

效果图:


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值