EllipseBy.h:
#ifndef _ELLIPSEBY_H_ #define _ELLIPSEBY_H_ #include "cocos2d.h" USING_NS_CC; #define PI 3.14159 //椭圆的参数信息 struct EllipseConfig { //椭圆a的长度 float ellipseA; //椭圆b的长度 float ellipseB; //椭圆的中心坐标 Vec2 cenPos; //是否逆时针旋转 bool isAntiClockwise; //目标开始旋转的位置,默认位置是在椭圆长轴右方,即值为0 float startAngle; //目标自身的角度 float selfAngle; }; class EllipseBy : public ActionInterval { public: EllipseBy(); ~EllipseBy(); //初始化函数,参数t为持续时间,config为椭圆参数 static EllipseBy * create(float t,const EllipseConfig & config); bool initWithDuration(float t,const EllipseConfig & config); //每帧更新当前椭圆坐标 virtual void update(float time) override; //在动作开始前调用 virtual void startWithTarget(Node *target) override; //动作的拷贝 virtual EllipseBy * clone() const override; //动作的逆序 virtual EllipseBy * reverse() const override; protected: //获得椭圆上当前点坐标 inline Vec2 & getPosWithEllipse(float t) { float angle = 2 * PI * ((m_config.isAntiClockwise ? t : (1 - t)) + m_config.startAngle / 360); return Vec2(m_config.ellipseA * cos(angle),m_config.ellipseB * sin(angle)); } private: EllipseConfig m_config; }; #endif
EllipseBy.cpp:
#include "EllipseBy.h" EllipseBy::EllipseBy() { } EllipseBy::~EllipseBy() { } EllipseBy * EllipseBy::create(float t,const EllipseConfig & config) { auto pAction = new EllipseBy(); if (pAction && pAction->initWithDuration(t,config)) { pAction->autorelease(); } else { CC_SAFE_DELETE(pAction); } return pAction; } bool EllipseBy::initWithDuration(float t,const EllipseConfig & config) { if (!ActionInterval::initWithDuration(t)) { return false; } m_config = config; return true; } EllipseBy * EllipseBy::clone() const { auto pAction = new EllipseBy(); pAction->initWithDuration(_duration,m_config); pAction->autorelease(); return pAction; } EllipseBy * EllipseBy::reverse() const { EllipseConfig resConfig = m_config; resConfig.isAntiClockwise = !m_config.isAntiClockwise; return EllipseBy::create(_duration,m_config); } void EllipseBy::startWithTarget(Node *target) { ActionInterval::startWithTarget(target); } void EllipseBy::update(float time) { if (_target) { Vec2 curPos = this->getPosWithEllipse(time); float tmpAngle = m_config.selfAngle / 180 * PI; float newX = curPos.x * cos(tmpAngle) + curPos.y * sin(tmpAngle); float newY = curPos.y * cos(tmpAngle) - curPos.x * sin(tmpAngle); _target->setPosition(m_config.cenPos + Vec2(newX,newY)); } }
LotteryTurnTest.h:
#ifndef _LOTTERY_TURN_TEST_H_ #define _LOTTERY_TURN_TEST_H_ #include "cocos2d.h" USING_NS_CC; class LotteryTurnTest : public cocos2d::Layer { public: LotteryTurnTest(); ~LotteryTurnTest(); static cocos2d::Scene * create(); virtual bool init(); protected: void onBtnCallback(Ref * obj); void onTurnEnd(); private: Sprite * m_turnBg; MenuItemSprite * m_turnArr; Sprite * m_pBg; ParticleSystemQuad * m_pElliRtt_1; ParticleSystemQuad * m_pElliRtt_2; ParticleSystemQuad * m_pCircle_1; ParticleSystemQuad * m_pCircle_2; }; #endif
LotteryTurnTest.cpp:
#include "LotteryTurnTest.h" #include "EllipseBy.h" LotteryTurnTest::LotteryTurnTest() : m_turnBg(nullptr),m_turnArr(nullptr),m_pBg(nullptr),m_pElliRtt_1(nullptr),m_pElliRtt_2(nullptr),m_pCircle_1(nullptr),m_pCircle_2(nullptr) { } LotteryTurnTest::~LotteryTurnTest() { } Scene * LotteryTurnTest::create() { auto scene = Scene::create(); auto pLayer = new LotteryTurnTest(); if (pLayer && pLayer->init()) { pLayer->autorelease(); scene->addChild(pLayer); return scene; } else { CC_SAFE_DELETE(pLayer); return NULL; } } bool LotteryTurnTest::init() { if (!Layer::init()) { return false; } auto bgSize = Director::getInstance()->getWinSize(); m_pBg = Sprite::create("LotteryTurn/bg_big.png"); m_pBg->setPosition(Vec2(bgSize.width / 2,bgSize.height / 2)); this->addChild(m_pBg); //添加标题 auto plabel = Label::createWithTTF("LotteryTurnTest","fonts/Marker Felt.ttf",30); plabel->setPosition(Vec2(bgSize.width / 2,bgSize.height * 0.9)); m_pBg->addChild(plabel); //添加转盘 m_turnBg = Sprite::create("LotteryTurn/turn_bg.png"); m_turnBg->setPosition(Vec2(bgSize.width / 2,bgSize.height / 2)); m_pBg->addChild(m_turnBg); //添加指针 auto arrNor = Sprite::create("LotteryTurn/turn_arrow.png"); auto arrSel = Sprite::create("LotteryTurn/turn_arrow.png"); arrSel->setColor(Color3B(190,190,190)); m_turnArr = MenuItemSprite::create(arrNor,arrSel,CC_CALLBACK_1(LotteryTurnTest::onBtnCallback,this)); m_turnArr->setPosition(Vec2(bgSize.width / 2,bgSize.height * 0.557)); m_turnArr->setScale(0.7); auto pMenu = Menu::createWithItem(m_turnArr); pMenu->setPosition(Vec2::ZERO); m_pBg->addChild(pMenu); //添加中奖之后的简单界面 auto awardLayer = LayerColor::create(Color4B(0,100)); awardLayer->setPosition(Point::ZERO); awardLayer->setTag(100); m_pBg->addChild(awardLayer,10); awardLayer->setVisible(false); return true; } void LotteryTurnTest::onBtnCallback(Ref * obj) { //防止多次点击 m_turnArr->setEnabled(false); srand(unsigned(time(NULL))); float angleZ = rand() % 720 + 720; auto pAction = EaseExponentialOut::create(RotateBy::create(4,Vec3(0,angleZ))); m_turnBg->runAction(Sequence::create(pAction,CallFunc::create(CC_CALLBACK_0(LotteryTurnTest::onTurnEnd,this)),NULL)); //添加椭圆旋转粒子效果 m_pElliRtt_1 = ParticleSystemQuad::create("LotteryTurn/whiteBall.plist"); m_pBg->addChild(m_pElliRtt_1); m_pElliRtt_2 = ParticleSystemQuad::create("LotteryTurn/yellowBall.plist"); m_pBg->addChild(m_pElliRtt_2); //椭圆旋转 EllipseConfig config; config.ellipseA = 100; config.ellipseB = 50; config.cenPos = m_turnBg->getPosition(); config.isAntiClockwise = true; config.startAngle = 0; config.selfAngle = 45; m_pElliRtt_1->runAction(RepeatForever::create( EllipseBy::create(2.5,config))); config.startAngle = 180; config.selfAngle = -45; m_pElliRtt_2->runAction(RepeatForever::create(EllipseBy::create(2.5,config))); //圈圈闪烁粒子效果 m_pCircle_1 = ParticleSystemQuad::create("LotteryTurn/bigCircle.plist"); m_pCircle_1->setPosition(m_turnBg->getPosition()); m_pBg->addChild(m_pCircle_1); m_pCircle_1->runAction(RepeatForever::create(RotateBy::create(5,angleZ)))); m_pCircle_2 = ParticleSystemQuad::create("LotteryTurn/smallCircle.plist"); m_pCircle_2->setPosition(m_turnBg->getPosition()); m_pBg->addChild(m_pCircle_2); m_pCircle_2->runAction(RepeatForever::create(RotateBy::create(5,angleZ)))); } void LotteryTurnTest::onTurnEnd() { m_pElliRtt_1->removeFromParentAndCleanup(true); m_pElliRtt_2->removeFromParentAndCleanup(true); m_pCircle_1->removeFromParentAndCleanup(true); m_pCircle_2->removeFromParentAndCleanup(true); //弹出抽中奖品 ((LayerColor *)m_pBg->getChildByTag(100))->setVisible(true); auto award = Sprite::create("LotteryTurn/award.png"); award->setAnchorPoint(Vec2(0.5,0)); award->setPosition(Vec2(m_pBg->getPositionX(),m_pBg->getPositionY() * 2)); this->addChild(award); auto bounce = EaseBounceOut::create(MoveBy::create(2,Vec2(0,-m_pBg->getPositionX() * 2))); award->runAction(Sequence::createWithTwoActions(bounce,CallFuncN::create([=](Node * node){ award->removeFromParentAndCleanup(true); ((LayerColor *)m_pBg->getChildByTag(100))->setVisible(false); m_turnArr->setEnabled(true); }))); }