加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

cocos2dx之实现扑克牌翻转效果的三种方法

发布时间:2020-12-14 16:50:19 所属栏目:百科 来源:网络整理
导读:*************************************************************************************** 时间: 2015-04-10 作者: Sharing_Li 转载注明出处:http://www.jb51.cc/article/p-oxjestnm-rx.html *******************************************************

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

时间:2015-04-10

作者:Sharing_Li

转载注明出处:http://www.52php.cn/article/p-oxjestnm-rx.html

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


最近写一款家乡的牌类游戏,自己玩玩,里面涉及到扑克牌的翻牌效果,这里简单来说一下:

一说到翻转,我马上想到了OrbitCamera这个家伙,虽然很少用,但知道它有这个效果,但代码写到一半发现事实情况是这样的:

我本意是打算将扑克牌背面转到90°,也就是与屏幕垂直,这个时候,再把扑克牌正面从90°位置转到0°即正面。但是同样是转到90°,各个背面的显示不一样。代码如下:

[cpp] view plain copy
  1. for(intj=1;j<=16;j++){
  2. m_cardBg.at(j-1)->runAction(Sequence::create(DelayTime::create(1)
  3. ,OrbitCamera::create(0.05+j/20.0,1,90,0),NULL));
  4. }

纳闷,然后上网查了查文档,说OrbitCamera是沿屏幕中心进行球面轨迹的旋转,乍一看不知道说的啥,OrbitCamera::create函数的参数也很多,然后分析了一下,好像知道了个三二一,见下图:

所谓的旋转90°也就是垂直球面指向球心。“上有政策,下有对策”,我这里弄了一个勉强的解决方案,也就是当动画运行到上图停止时,隐藏扑克牌背面,让事先隐藏(先用orbitcamera旋转90°再隐藏)的扑克牌正面图片显示出来,然后向相反的方向调用orbitcamera旋转90°。看效果图:

在看看代码实现:

copy

    ,Hide::create()
  1. {
  2. m_cardVec.at(j-1)->runAction(Sequence::create(
  3. Show::create(),
  4. OrbitCamera::create(0.05+j/20.0,-90,248)"> }),NULL));
  5. m_cardVec.at(j-1)->runAction(OrbitCamera::create(0.02,0));
  6. 基本上有模有样了,这就是第一种方法。第二种方法其实也是用的orbitcamera实现的,勉强凑个数。先看下效果图:

    可以感觉的到,效果比之前的更流畅。并且只需在之前的代码基础上加上一行代码。第一种方法弄好后,我总感觉可以再优化,刚开始打算这样弄,以中间的一张图为比较对象,将每一张图的中点,球心,和中间一张图的中心,构成三角形,比较tan值,从而设置其要旋转的角度,但是最后失败了,效果不佳,放弃了。最后,我打算进入到OrbitCamera的源代码看看。最后看到OrbitCamera::update函数中调用了一个setEye函数,然后突然想到之前第二张分析图里的箭头都指向球心,感觉就像许多眼睛都盯着球心那个地方一样。然后继续跟踪:setEye—》ActionCamera::updateTransform—》Node::setAdditionalTransform,然后发现这句代码:_transformUpdated=_transformDirty=_inverseDirty=true;这个跟对象的绘制有关,然后在Node.cpp里找到visit函数,发现跟director在搞鬼,然后继续跳到director,然后真相大白了。见如下代码:

      /**
    1. *@briefPossibleOpenGLprojectionsusedbydirector
    2. */
    3. enumclassProjection
    4. {
    5. ///Setsa2Dprojection(orthogonalprojection).
    6. _2D,
    7. ///Setsa3Dprojectionwithafovy=60,znear=0.5fandzfar=1500.
    8. _3D,0); background-color:inherit">///Itcalls"updateProjection"ontheprojectiondelegate.
    9. CUSTOM,0); background-color:inherit">///Defaultprojectionis3Dprojection.
    10. DEFAULT=_3D,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> };

      voidDirector::setProjection(Projectionprojection)
    1. Sizesize=_winSizeInPoints;
    2. setViewport();
    3. switch(projection)
    4. caseProjection::_2D:
    5. loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
    6. #ifCC_TARGET_PLATFORM==CC_PLATFORM_WP8
    7. if(getOpenGLView()!=nullptr)
    8. multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION,getOpenGLView()->getOrientationMatrix());
    9. }
    10. #endif
    11. Mat4orthoMatrix;
    12. Mat4::createOrthographicOffCenter(0,size.width,size.height,-1024,1024,&orthoMatrix);
    13. multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION,orthoMatrix);
    14. loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    15. break;
    16. }
    17. caseProjection::_3D:
    18. floatzeye=this->getZEye();
    19. Mat4matrixPerspective,matrixLookup;
    20. #ifCC_TARGET_PLATFORM==CC_PLATFORM_WP8
    21. //ifneeded,weneedtoaddarotationforLandscapeorientationsonWindowsPhone8sinceitisalwaysinPortraitMode
    22. GLView*view=getOpenGLView();
    23. if(getOpenGLView()!=nullptr)
    24. #endif
    25. //issue#1334
    26. Mat4::createPerspective(60,(GLfloat)size.width/size.height,10,zeye+size.height/2,&matrixPerspective);
    27. Vec3eye(size.width/2,size.height/2,zeye),center(size.width/2,0.0f),up(0.0f,1.0f,0.0f);
    28. Mat4::createLookAt(eye,center,up,&matrixLookup);
    29. loadIdentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    30. break;
    31. caseProjection::CUSTOM:
    32. //ProjectionDelegateisnolongerneeded
    33. //sincetheevent"PROJECTIONCHANGED"isemitted
    34. default:
    35. CCLOG("cocos2d:Director:unrecognizedprojection");
    36. _projection=projection;
    37. GL::setProjectionMatrixDirty();
    38. _eventDispatcher->dispatchEvent(_eventProjectionChanged);
    39. }
    然后我在初始化的时候加入下面的代码,问题就解决了:

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

    记得动画播放完之后,要还原到默认值,也就是_3D,以免对其他部分的显示造成影响。最后看看第三种方法,用到了ScaleTo,大家可能疑惑为什么这个缩放函数可以进行旋转,当我们对精灵进行如下操作的时候,setScaleX(-1),作用是以Y轴为对称轴反转,为什么呢,因为-1就是从相反的方向进行缩放,如果是-2,就是从相反的方向缩放两倍。那么同理,ScaleTo就可以有翻牌的效果啦。看如下用ScaleTo实现的效果图:



    代码如下:

      Hide::create()
    1. ScaleTo::create(0.05+j/20.0,248)"> m_cardVec.at(j-1)->setFlippedX(true);
    2. }

    到这里结束了, 免费下载资源

    (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读