700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 仿真树叶飘落效果的实现

仿真树叶飘落效果的实现

时间:2020-10-03 20:56:11

相关推荐

仿真树叶飘落效果的实现

独角兽企业重金招聘Python工程师标准>>>

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

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

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

#ifndef__LEAF_H__#define__LEAF_H__#include"cocos2d.h"USING_NS_CC;classLeaf:publiccocos2d::CCLayer{public:virtualboolinit();voidresetLeafPos(CCNode*sender);//叶片位置重置函数voidplayLeafAnim(CCSprite*spriteLeaf);//下落过程实现函数LAYER_NODE_FUNC(Leaf);};#endif//__LEAF_H__

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

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

#include<iostream>#include<ctime>#include<cstdlib>#include"Leaf.h"usingnamespacestd;enum{TAG_LEAF1=101,TAG_LEAF2};

初始化树叶精灵的设定:

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;}

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

//叶子飘落动作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,0,0,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,-1);//摆动合成//动作执行->同时执行所有动作spriteLeaf->runAction(CCSpawn::actions(putdown,baidong,fz3d,NULL));}

现在叶子飘落的主干就设定完毕了,其实看上去并不复杂,就是三个动作:下落+摆动+翻转,未来使落叶更自然,我们尽可能的在数据可变的范围内使用随机参数,我这里用了系统时间做种子来产生随机数,但是我感觉产生的随机数还是不够理想,如果你有更好的种子,可以告诉我。其实还有很多参数可以在限定范围内使用随机数,由于时间关系我没有逐个去调试,而是直接设定了一个固定值。有时间你可以逐个设定实验,找到最佳的数据范围

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

//重置叶子的位置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;//随机生成叶子的起始位置srand((UINT)GetCurrentTime());intiRand=(rand()%200);if(iTag==TAG_LEAF1){pos=ccp(iRand,600);fAngle=30;}else{pos=ccp(iRand,570);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值的大小为你的精灵被挡住部分的像素值

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。