今天心血来潮做了个扇形按钮,想起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);
效果图: