cocos2dx之實現撲克牌翻轉效果的三種方法,cocos2dx撲克牌

來源:互聯網
上載者:User

cocos2dx之實現撲克牌翻轉效果的三種方法,cocos2dx撲克牌

***************************************************************************************

時間:2015-04-10

作者:Sharing_Li

轉載註明出處:http://blog.csdn.net/sharing_li/article/details/44980493

***************************************************************************************


       最近寫一款家鄉的牌類遊戲,自己玩玩,裡面涉及到撲克牌的翻牌效果,這裡簡單來說一下:

       一說到翻轉,我馬上想到了OrbitCamera這個傢伙,雖然很少用,但知道它有這個效果,但代碼寫到一半發現事實情況是這樣的:



        我本意是打算將撲克牌背面轉到90°,也就是與螢幕垂直,這個時候,再把撲克牌正面從90°位置轉到0°即正面。但是同樣是轉到90°,各個背面的顯示不一樣。代碼如下:

for (int j = 1; j <= 16; j++) {        m_cardBg.at(j - 1)->runAction(Sequence::create(DelayTime::create(1)                                      ,OrbitCamera::create(0.05 + j / 20.0, 1, 0, 0, 90, 0, 0),NULL));    }

        納悶,然後上網查了查文檔,說OrbitCamera是沿螢幕中心進行球面軌跡的旋轉,乍一看不知道說的啥,OrbitCamera::create函數的參數也很多,然後分析了一下,好像知道了個三二一,見:


      所謂的旋轉90°也就是垂直球面指向球心。“上有政策,下有對策”,我這裡弄了一個勉強的解決方案,也就是當動畫運行到停止時,隱藏撲克牌背面,讓事先隱藏(先用orbitcamera旋轉90°再隱藏)的撲克牌正面圖片顯示出來,然後向相反的方向調用orbitcamera旋轉90°。看:


       在看看代碼實現:

for (int j = 1; j <= 16; j++) {        m_cardBg.at(j - 1)->runAction(Sequence::create(DelayTime::create(1)                                      ,OrbitCamera::create(0.05 + j / 20.0, 1, 0, 0, 90, 0, 0)                                       ,Hide::create()                                       ,CallFunc::create([=]                                                      {                                                          m_cardVec.at(j - 1)->runAction(Sequence::create(                                                               Show::create(),                                                               OrbitCamera::create(0.05 + j / 20.0, 1, 0, 90, -90, 0, 0), NULL));                                                      }),NULL));                m_cardVec.at(j - 1)->runAction(OrbitCamera::create(0.02, 1, 0, 0, 90, 0, 0));    }

        基本上有模有樣了,這就是第一種方法。第二種方法其實也是用的orbitcamera實現的,勉強湊個數。先看下:


      可以感覺的到,效果比之前的更流暢。並且只需在之前的代碼基礎上加上一行代碼。第一種方法弄好後,我總感覺可以再最佳化,剛開始打算這樣弄,以中間的一張圖為比較對象,將每一張圖的中點,球心,和中間一張圖的中心,構成三角形,比較tan值,從而設定其要旋轉的角度,但是最後失敗了,效果不佳,放棄了。最後,我打算進入到OrbitCamera的原始碼看看。最後看到OrbitCamera::update函數中調用了一個setEye函數,然後突然想到之前第二張分析圖裡的箭頭都指向球心,感覺就像許多眼睛都盯著球心那個地方一樣。然後繼續跟蹤:setEye—》ActionCamera::updateTransform—》Node::setAdditionalTransform,然後發現這句代碼:_transformUpdated = _transformDirty = _inverseDirty =true;這個跟對象的繪製有關,然後在Node.cpp裡找到visit函數,發現跟director在搞鬼,然後繼續跳到director,然後真相大白了。見如下代碼:

/**     * @brief Possible OpenGL projections used by director     */    enum class Projection    {        /// Sets a 2D projection (orthogonal projection).        _2D,                /// Sets a 3D projection with a fovy=60, znear=0.5f and zfar=1500.        _3D,                /// It calls "updateProjection" on the projection delegate.        CUSTOM,                /// Default projection is 3D projection.        DEFAULT = _3D,    };

void Director::setProjection(Projection projection){    Size size = _winSizeInPoints;    setViewport();    switch (projection)    {        case Projection::_2D:        {            loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);#if CC_TARGET_PLATFORM == CC_PLATFORM_WP8            if(getOpenGLView() != nullptr)            {                multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION, getOpenGLView()->getOrientationMatrix());            }#endif            Mat4 orthoMatrix;            Mat4::createOrthographicOffCenter(0, size.width, 0, size.height, -1024, 1024, &orthoMatrix);            multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION, orthoMatrix);            loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);            break;        }                    case Projection::_3D:        {            float zeye = this->getZEye();            Mat4 matrixPerspective, matrixLookup;            loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);            #if CC_TARGET_PLATFORM == CC_PLATFORM_WP8            //if needed, we need to add a rotation for Landscape orientations on Windows Phone 8 since it is always in Portrait Mode            GLView* view = getOpenGLView();            if(getOpenGLView() != nullptr)            {                multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION, getOpenGLView()->getOrientationMatrix());            }#endif            // issue #1334            Mat4::createPerspective(60, (GLfloat)size.width/size.height, 10, zeye+size.height/2, &matrixPerspective);            multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION, matrixPerspective);            Vec3 eye(size.width/2, size.height/2, zeye), center(size.width/2, size.height/2, 0.0f), up(0.0f, 1.0f, 0.0f);            Mat4::createLookAt(eye, center, up, &matrixLookup);            multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION, matrixLookup);                        loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);            break;        }        case Projection::CUSTOM:            // Projection Delegate is no longer needed            // since the event "PROJECTION CHANGED" is emitted            break;        default:            CCLOG("cocos2d: Director: unrecognized projection");            break;    }    _projection = projection;    GL::setProjectionMatrixDirty();    _eventDispatcher->dispatchEvent(_eventProjectionChanged);}
       然後我在初始化的時候加入下面的代碼,問題就解決了:

Director::getInstance()->setProjection(cocos2d::DisplayLinkDirector::Projection::_2D);

       記得動畫播放完之後,要還原到預設值,也就是_3D,以免對其他部分的顯示造成影響。最後看看第三種方法,用到了ScaleTo,大家可能疑惑為什麼這個縮放函數可以進行旋轉,當我們對精靈進行如下操作的時候,setScaleX(-1),作用是以Y軸為對稱軸反轉,為什麼呢,因為-1就是從相反的方向進行縮放,如果是-2,就是從相反的方向縮放兩倍。那麼同理,ScaleTo就可以有翻牌的效果啦。看如下用ScaleTo實現的:



      代碼如下:

for (int j = 1; j <= 16; j++) {        m_cardBg.at(j - 1)->runAction(Sequence::create(DelayTime::create(1)                                                       ,ScaleTo::create(0.05 + j / 20.0, -1,1),                                                       Hide::create()                                                       ,CallFunc::create([=]                                                                         {                                                                             m_cardVec.at(j - 1)->runAction(Sequence::create(                                                                                                                             Show::create(),                                                                                                                             ScaleTo::create(0.05 + j / 20.0, -1,1), NULL));                                                                         }),NULL));                m_cardVec.at(j - 1)->setFlippedX(true);    }

到這裡結束了,免費下載資源

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.