cocos2dx 利用CCOrbitCamera实现扑克牌翻牌效果

【注意】CCSpriteBatchNode不支持CCOrbitCamera动画。如果不需要用到CCSpriteBatchNode的话可以用下面这种方式:


#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"

using namespace cocos2d;
using namespace CocosDenshion;

CCScene* HelloWorld::scene()
{
    CCScene *scene = CCScene::create();
    HelloWorld *layer = HelloWorld::create();
    scene->addChild(layer);
    return scene;
}
bool HelloWorld::init()
{
    if ( !cclayer::init() )
    {
        return false;
    }
    size = CCDirector::sharedDirector()->getWinSize();
    
    //加一背景
    cclayerColor* background = cclayerColor::create(ccc4(255,180,255,255),size.width,size.height);
    this->addChild(background);
    
    actionIsDone = true;//标示动作是否完成
    
    createPoker(); //创建扑克
    
    return true;
}

//创建扑克
void HelloWorld::createPoker()
{
    //扑克牌正面
    CCSprite* pokerFront = CCSprite::create("poker_front.png");
    pokerFront->setVisible(false);
    pokerFront->setPosition(ccp(size.width/2,size.height/2));
    this->addChild(pokerFront,1,123);
  
    //扑克牌反面
    CCSprite* pokerBack = CCSprite::create("poker_back.png");
    pokerBack->setPosition(pokerFront->getPosition());
    this->addChild(pokerBack,321);
}
//翻牌动作
void HelloWorld::startOrbitaction()
{
    //扑克牌正面
    CCSprite* pokerFront = (CCSprite*)this->getChildByTag(123);
    //扑克牌反面
    CCSprite* pokerBack = (CCSprite*)this->getChildByTag(321);
    
    float orbitTime = 1;
    if (pokerFront->isVisible() == false && actionIsDone == true) {
        actionIsDone = false;
        //第一个参数是旋转的时间,第二个参数是起始半径,第三个参数半径差,第四个参数是起始Z角,第五个参数是旋转Z角差,第六个参数是起始X角,最后一个参数旋转X角差,
        CCOrbitCamera* orbitFront = CCOrbitCamera::create(orbitTime,270,90,0);
        CCSequence* sequenceFront = CCSequence::createWithTwoActions(CCShow::create(),orbitFront);
        CCTargetedAction* targetFront = CCTargetedAction::create(pokerFront,sequenceFront);

        CCOrbitCamera* orbitBack = CCOrbitCamera::create(orbitTime,0);
        pokerBack->runAction(CCSequence::create(orbitBack,CCHide::create(),targetFront,CCCallFunc::create(this,callfunc_selector(HelloWorld::actionIsDownFunc)),NULL));
    }else if(pokerFront->isVisible() == true && actionIsDone == true){
        actionIsDone = false;
        CCOrbitCamera* orbitFront = CCOrbitCamera::create(orbitTime,orbitFront);
        CCTargetedAction* targetFront = CCTargetedAction::create(pokerBack,sequenceFront);
        
        CCOrbitCamera* orbitBack = CCOrbitCamera::create(orbitTime,0);
        pokerFront->runAction(CCSequence::create(orbitBack,NULL));
    }
}

void HelloWorld::actionIsDownFunc()
{
    actionIsDone = true;
}

bool HelloWorld::ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent)
{
    //翻牌动作
    startOrbitaction();
    return true;
}

void HelloWorld::ccTouchMoved(CCTouch *pTouch,CCEvent *pEvent){}
void HelloWorld::ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent){}
void HelloWorld::onEnter()
{
    CCDirector::sharedDirector()->getTouchdispatcher()->addTargetedDelegate(this,false);
    cclayer::onEnter();
}
void HelloWorld::onExit()
{
    CCDirector::sharedDirector()->getTouchdispatcher()->removeDelegate(this);
    cclayer::onExit();
}
HelloWorld::~HelloWorld(){}



第二种方式:如果考虑到性能问题要用到CCSpriteBatchNode的话,那么可以使用CCRotateto来实现类似的功能

//扑克牌正面(带数字的是正面)
    CCSprite* pokerFront = CCSprite::createWithSpriteFrameName("card_fg.png");
    // 数字
    CCSprite* pokerNumber = CCSprite::createWithSpriteFrameName("18.png");
    //扑克牌反面
    CCSprite* pokerBack = CCSprite::createWithSpriteFrameName("card_bg.png");
    
    pokerFront->setPosition(ccp(m_size.width/2,m_size.height/2));
    pokerBack->setPosition(ccp(m_size.width/2,m_size.height/2));
    pokerNumber->setPosition(ccp(m_size.width/2,m_size.height/2));
    
    m_spriteBatchNode->addChild(pokerFront);
    m_spriteBatchNode->addChild(pokerNumber);
    m_spriteBatchNode->addChild(pokerBack);
    
    
    CCRotateto* rtFont1 = CCRotateto::create(0.f,0.f,-90.f);
    CCRotateto* rtNumber1 = CCRotateto::create(0.f,-90.f);
    
    // 先将前景和数字旋转到要进行反过来使用的位置待用
    pokerFront->runAction(rtFont1);
    pokerNumber->runAction(rtNumber1);
    
    // 将牌的背面向Y轴旋转90度,这时候该面刚好旋转到被隐藏的位置
    CCRotateto* rtBack = CCRotateto::create(0.5f,90.f);
    // 讲牌的正面和数组从刚才的位置旋转到0度,这样子刚好和牌的背面动画衔接起来
    CCRotateto* rtFont2 = CCRotateto::create(0.5f,0.f);
    CCTargetedAction* ta = CCTargetedAction::create(pokerFront,rtFont2);
    CCRotateto* rtNumber2 = CCRotateto::create(0.5f,0.f);
    CCTargetedAction* taa = CCTargetedAction::create(pokerNumber,rtNumber2);
    
    pokerBack->runAction(CCSequence::create(rtBack,CCSpawn::create(ta,taa,nullptr),nullptr));

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...