cocos2d-x学习笔记五仿真树叶飘落效果的实现精灵旋转、翻转、钟摆运动等综合运用

cocos2d-x学习笔记(五)仿真树叶飘落效果的实现(精灵旋转、翻转、钟摆运动等综合运用)

分类C++学习cocos2d-x 6775人阅读评论(5)收藏举报
ufolr原创,转载请注明:

转载自ufolr博客 原文连接:http://www.jb51.cc/article/p-mrdyjsly-dt.html

最近项目中需要一个落叶的效果,本来想用粒子特效来实现,但是几经调试,虽然调出了落叶的效果,但是并不是十分理想,最大的不足就是落叶是平面的,没有立体感,虽然把落叶做小之后却是立体感的感觉会有所缓解,但总不能把树叶无限的缩小吧,而且立体感的缺失在粒子特效中确实是一个始终存在的问题。作为一个最求品质的程序猿,最终还是决定自己设精灵动作来实现。

在分析了粒子特效实现的原理并在国内外论坛上爬了半天,最后边实验边修改,终于完成了一个可行的仿真感较强的立体的落叶效果,现在就拿出来跟大家分享一下。

原理->树叶飘落动作分析:

树叶下落过程分解为下落+摆动叶片自传

也就是只要将这三个动作实现,并同时执行就可以实现树叶飘落的效果

下面就拿出代码具体解析实现过程:

老规矩,先上.h的内容,.h就不多解释了:

  1. #ifndef__LEAF_H__
  2. #define__LEAF_H__
  3. #include"cocos2d.h"
  4. USING_NS_CC;
  5. classLeaf:publiccocos2d::cclayer
  6. {
  7. public:
  8. virtualboolinit();
  9. voidresetLeafPos(CCNode*sender);//叶片位置重置函数
  10. voidplayLeafAnim(CCSprite*spriteLeaf);//下落过程实现函数
  11. LAYER_NODE_FUNC(Leaf);
  12. };
  13. #endif//__LEAF_H__

接下来是具体的实现,为了我们能不断的产生自然、随和的落叶,我们分三步来完成:

1:第一次初始化;2:落叶动作的实现;3:下落动作完成重新设定落叶开始。

代码,先看看用到的头文件

#include<iostream>

  • #include<ctime>
  • #include<cstdlib>
  • #include"Leaf.h"
  • usingnamespacestd;
  • enum{TAG_LEAF1=101,TAG_LEAF2};
  • 初始化树叶精灵的设定:

    <spanstyle="font-size:12px;">boolLeaf::init()

  • CCSprite*spriteLeaf1=CCSprite::spriteWithFile("img_yezi_1.png");
  • spriteLeaf1->setRotation(30);//旋转角度
  • spriteLeaf1->setAnchorPoint(ccp(0.5,3));//设置精灵锚点
  • spriteLeaf1->setPosition(ccp(450,500));//叶子1第一次初始位置
  • spriteLeaf1->setScale(0.5);//设置叶片大小
  • this->addChild(spriteLeaf1,100,TAG_LEAF1);
  • this->playLeafAnim(spriteLeaf1);//调用play函数播实现叶动作
  • CCSprite*spriteLeaf2=CCSprite::spriteWithFile("img_yezi_2.png");
  • spriteLeaf2->setRotation(50);
  • spriteLeaf2->setAnchorPoint(ccp(0.5,3));
  • spriteLeaf2->setPosition(ccp(200,540));
  • spriteLeaf2->setScale(0.5);
  • this->addChild(spriteLeaf2,101,TAG_LEAF2);
  • this->playLeafAnim(spriteLeaf2);
  • returntrue;
  • }</span>

  • 将精灵的锚点设定在其高度的3倍的位置,加上旋转动作后,叶片会产生单摆的动作效果。再加上下落的动作,就会有树叶飘落的感觉了。

    <spanstyle="font-size:12px;">//叶子飘落动作

  • voidLeaf::playLeafAnim(CCSprite*spriteLeaf)
  • {
  • intiTag=spriteLeaf->getTag();
  • cclog("playtag%d",iTag);
  • ccTimetime,roTime;
  • floatfAngle1,fAngle2;
  • if(iTag==TAG_LEAF1)
  • cclog("tag1");
  • time=10;//叶子下落的时间
  • roTime=2.5;//叶子单向摆动一次时间
  • fAngle1=-80;//叶子逆时针摆动角度
  • fAngle2=80;//顺时针摆动角度
  • }
  • else
  • cclog("tag2");
  • time=14;
  • roTime=3.2;
  • fAngle1=-100;
  • fAngle2=100;
  • cclog("rotime%ffAngle1%ffAngle2%f",roTime,fAngle1,fAngle1);
  • //随机生成叶子横向偏移值
  • srand((UINT)GetCurrentTime());
  • intiRandPos=rand()%250;
  • cclog("Pianyi%d",iRandPos);
  • //叶子所运动到的位置
  • CCMoveto*moveto=CCMoveto::actionWithDuration(time,ccp(CCDirector::sharedDirector()->getWinSize().width-iRandPos,30));
  • CCCallFuncN*actDone=CCCallFuncN::actionWithTarget(this,callfuncN_selector(Leaf::resetLeafPos));
  • CCFiniteTimeAction*putdown=CCSequence::actions(moveto,actDone,NULL);
  • //叶子旋转动作
  • CCRotateBy*rotaBy1=CCRotateBy::actionWithDuration(roTime,fAngle1);
  • CCRotateBy*rotaBy2=CCRotateBy::actionWithDuration(roTime,fAngle2);
  • //叶子翻转动作
  • spriteLeaf->setVertexZ(60);//设置深度抬高60,避免出现使用CCOrbitCamera实现空间翻转时产生错位和遮挡等问题
  • //CCDirector::sharedDirector()->setDepthTest(false);
  • //关闭深度测试同样可以避免上述问题,不过,推荐使用深度设置setVertexZ来正确解决,因为有时你可能需要遮挡的效果关闭深度测试后将造成遮挡效果的缺失
  • CCOrbitCamera*orbit=CCOrbitCamera::actionWithDuration(8,1,360,45,0);
  • //让树叶精灵始终执行三维翻转的动作
  • CCRepeat*fz3d=CCRepeat::actionWithAction(orbit,-1);//无限循环执行叶片翻转的动作
  • //CCRepeatForever*fz3d=CCRepeatForever::actionWithAction(orbit);
  • //由于下面使用CCSpawn同时执行动作,所以不可以使用无限次数类型的动作,而因使用有线次数循环CCRepeat将循环次数设置为-1
  • //用CCEaseInOut包装落叶摆动的动作,让树叶的进入、出现更自然(淡入淡出效果
  • CCEaseInOut*ease1=CCEaseInOut::actionWithAction(rotaBy1,3);
  • CCEaseInOut*ease2=CCEaseInOut::actionWithAction(rotaBy2,3);
  • //摆动动作合成
  • CCFiniteTimeAction*seq2=CCSequence::actions(ease1,ease2,NULL);//依次执行顺时针、逆时针摆动
  • CCRepeat*baidong=CCRepeat::actionWithAction(seq2,0)">//摆动合成
  • //动作执行->同时执行所有动作
  • spriteLeaf->runAction(CCSpawn::actions(putdown,baidong,fz3d,NULL));
  • }</span>
  • 现在叶子飘落的主干就设定完毕了,其实看上去并不复杂,就是三个动作:下落+摆动+翻转,未来使落叶更自然,我们尽可能的在数据可变的范围内使用随机参数,我这里用了系统时间做种子来产生随机数,但是我感觉产生的随机数还是不够理想,如果你有更好的种子,可以告诉我。其实还有很多参数可以在限定范围内使用随机数,由于时间关系我没有逐个去调试,而是直接设定了一个固定值。有时间你可以逐个设定实验,找到最佳的数据范围。

    现在为了使我们的落叶能够源源不断的产生,我们还需要让落叶的产生和消亡循环起来:

    //重置叶子的位置

  • voidLeaf::resetLeafPos(CCNode*sender)
  • intiTag=int(sender->getTag());//获得被重置叶片的标签
  • intiZoder=int(sender->getZOrder());//获取被重置叶片的z轴值
  • sender->removeFromParentAndCleanup(true);//清除已经落到底点的叶子
  • charsImg[15]="img_yezi_1.png";
  • _snprintf(sImg,sizeof(sImg),"img_yezi_%d.png",iTag%100);
  • CCPointpos;
  • floatfAngle;
  • //随机生成叶子的起始位置
  • UINT)GetCurrentTime());
  • intiRand=(rand()%200);
  • if(iTag==TAG_LEAF1)
  • pos=ccp(iRand,600);
  • fAngle=30;
  • fAngle=50;
  • }
  • //重新生成新的叶片,在起点处释放
  • CCSprite*spriteLeaf=CCSprite::spriteWithFile(sImg);
  • spriteLeaf->setScale(0.5);
  • spriteLeaf->setAnchorPoint(ccp(0.5,3));
  • spriteLeaf->setRotation(fAngle);
  • spriteLeaf->setPosition(pos);
  • this->addChild(spriteLeaf,iZoder,iTag);
  • this->playLeafAnim(spriteLeaf);//重置后的树叶再次执行飘落动作

  • 这样3d仿真的落叶的效果就基本实现了,为了节约时间,这里只写了2片叶子的情况,多片叶子的情况可以举一反三,多加几片叶子就行。这里需要注意的是在使用CCOrbitCamera来实现三维空间的翻转时,由于openGL绘图的关系,我们得将精灵的深度设置上浮,以避免openGL绘图时精灵的部分被后面的色彩遮挡。

    解决遮挡问题可以直接关闭深度测试CCDirector::sharedDirector()->setDepthTest(false);

    也可以设置精灵VertexZ上浮spriteLeaf->setVertexZ(60);

    如果你的程序不需要深度测试,你大可以直接关了它,但是你不能确定是的程序是否每个地方都没有用到深度测试,所以,推荐设置VertexZ值来避免你的精灵被遮挡。VertexZ值的大小为你的精灵被挡住部分的像素值。

  • 版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

    相关推荐


        本文实践自 RayWenderlich、Ali Hafizji 的文章《How To Create Dynamic Textures with CCRenderTexture in Cocos2D 2.X》,文中使用Cocos2D,我在这里使用Cocos2D-x 2.1.4进行学习和移植。在这篇文章,将会学习到如何创建实时纹理、如何用Gimp创建无缝拼接纹
    Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@163.com微信公众号:HopToad 欢迎转载,转载标注出处:http://blog.csdn.netotbaron/article/details/424343991.  软件准备 下载地址:http://cn.cocos2d-x.org/download 2.  简介2.1         引用C
    第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从Cocos2D-x官网上下载,进入网页http://www.cocos2d-x.org/download,点击Cocos2d-x以下的Download  v3.0,保存到自定义的文件夹2:从python官网上下载。进入网页https://www.python.org/downloads/,我当前下载的是3.4.0(当前最新
        Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发引擎,易学易用,支持多种智能移动平台。官网地址:http://cocos2d-x.org/当前版本:2.0    有很多的学习资料,在这里我只做为自己的笔记记录下来,错误之处还请指出。在VisualStudio2008平台的编译:1.下载当前稳
    1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《最强大脑》娱乐节目。将2048改造成一款挑战玩家对数字记忆的小游戏。邮箱:appdevzw@163.com微信公众号:HopToadAPK下载地址:http://download.csdn.net/detailotbaron/8446223源码下载地址:http://download.csdn.net/
       Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试以QtCreatorIDE来进行CMake构建。Cocos2d-x3.X地址:https://github.com/cocos2d/cocos2d-x1.打开QtCreator,菜单栏→"打开文件或项目...",打开cocos2d-x目录下的CMakeLists.txt文件;2.弹出CMake向导,如下图所示:设置
     下载地址:链接:https://pan.baidu.com/s/1IkQsMU6NoERAAQLcCUMcXQ提取码:p1pb下载完成后,解压进入build目录使用vs2013打开工程设置平台工具集,打开设置界面设置: 点击开始编译等待编译结束编译成功在build文件下会出现一个新文件夹Debug.win32,里面就是编译
    分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net前言上次用象棋演示了cocos2dx的基本用法,但是对cocos2dx并没有作深入的讨论,这次以超级马里奥的源代码为线索,我们一起来学习超级马里奥的实
    1. 圆形音量button事实上作者的本意应该是叫做“电位计button”。可是我觉得它和我们的圆形音量button非常像,所以就这么叫它吧~先看效果:好了,不多解释,本篇到此为止。(旁白: 噗。就这样结束了?)啊才怪~我们来看看代码:[cpp] viewplaincopyprint?CCContro
    原文链接:http://www.cnblogs.com/physwf/archive/2013/04/26/3043912.html为了进一步深入学习贯彻Cocos2d,我们将自己写一个场景类,但我们不会走的太远,凡是都要循序渐进,哪怕只前进一点点,那也至少是前进了,总比贪多嚼不烂一头雾水的好。在上一节中我们建
    2019独角兽企业重金招聘Python工程师标准>>>cocos2d2.0之后加入了一种九宫格的实现,主要作用是用来拉伸图片,这样的好处在于保留图片四个角不变形的同时,对图片中间部分进行拉伸,来满足一些控件的自适应(PS: 比如包括按钮,对话框,最直观的形象就是ios里的短信气泡了),这就要求图
    原文链接:http://www.cnblogs.com/linji/p/3599478.html1.环境和工具准备Win7VS2010/2012,至于2008v2版本之后似乎就不支持了。 2.安装pythonv.2.0版本之前是用vs模板创建工程的,到vs2.2之后就改用python创建了。到python官网下载版本2.7.5的,然后
    环境:ubuntu14.04adt-bundle-linux-x86_64android-ndk-r9d-linux-x86_64cocos2d-x-3.0正式版apache-ant1.9.3python2.7(ubuntu自带)加入环境变量exportANDROID_SDK_ROOT=/home/yangming/adt-bundle-linux/sdkexportPATH=${PATH}:/$ANDROID_SDK_ROOTools/export
    1开发背景游戏程序设计涉及了学科中的各个方面,鉴于目的在于学习与进步,本游戏《FlappyBird》采用了两个不同的开发方式来开发本款游戏,一类直接采用win32底层API来实现,另一类采用当前火热的cocos2d-x游戏引擎来开发本游戏。2需求分析2.1数据分析本项目要开发的是一款游
    原文链接:http://www.cnblogs.com/linji/p/3599912.html//纯色色块控件(锚点默认左下角)CCLayerColor*ccc=CCLayerColor::create(ccc4(255,0,0,128),200,100);//渐变色块控件CCLayerGradient*ccc=CCLayerGradient::create(ccc4(255,0,0,
    原文链接:http://www.cnblogs.com/linji/p/3599488.html//载入一张图片CCSprite*leftDoor=CCSprite::create("loading/door.png");leftDoor->setAnchorPoint(ccp(1,0.5));//设置锚点为右边中心点leftDoor->setPosition(ccp(240,160));/
    为了答谢广大学员对智捷课堂以及关老师的支持,现购买51CTO学院关老师的Cocos2d-x课程之一可以送智捷课堂编写图书一本(专题可以送3本)。一、Cocos2d-x课程列表:1、Cocos2d-x入门与提高视频教程__Part22、Cocos2d-x数据持久化与网络通信__Part33、Cocos2d-x架构设计与性能优化内存优
    Spawn让多个action同时执行。Spawn有多种不同的create方法,最终都调用了createWithTwoActions(FiniteTimeAction*action1,FiniteTimeAction*action2)方法。createWithTwoActions调用initWithTwoActions方法:对两个action变量初始化:_one=action1;_two=action2;如果两个a
    需要环境:php,luajit.昨天在cygwin上安装php和luajit环境,这真特么是一个坑。建议不要用虚拟环境安装打包环境,否则可能会出现各种莫名问题。折腾了一下午,最终将环境转向linux。其中,luajit的安装脚本已经在quick-cocos2d-x-develop/bin/中,直接luajit_install.sh即可。我的lin
    v3.0相对v2.2来说,最引人注意的。应该是对触摸层级的优化。和lambda回调函数的引入(嗯嗯,不枉我改了那么多类名。话说,每次cocos2dx大更新。总要改掉一堆类名函数名)。这些特性应该有不少人研究了,所以今天说点跟图片有关的东西。v3.0在载入图片方面也有了非常大改变,仅仅只是