如何实现精灵在js 指定范围随机数内的随机运动

仿真树叶飘落效果的实现(精灵旋转、翻转、钟摆运动等综合运用) - cocos2d - 小组 - 博客园
11:59 来自
原创,转载请注明:
转载自的博客 原文连接:
& && & & &最近项目中需要一个落叶的效果,本来想用粒子特效来实现,但是几经调试,虽然调出了落叶的效果,但是并不是十分理想,最大的不足就是落叶是平面的,没有立体感,虽然把落叶做小之后却是立体感的感觉会有所缓解,但总不能把树叶无限的缩小吧,而且立体感的缺失在粒子特效中确实是一个始终存在的问题。作为一个最求品质的程序猿,最终还是决定自己设精灵动作来实现。
& & & & &在分析了粒子特效实现的原理并在国内外论坛上爬了半天,最后边实验边修改,终于完成了一个可行的仿真感较强的立体的落叶效果,现在就拿出来跟大家分享一下。
原理-&树叶飘落动作分析:
& & & & &树叶下落过程分解为:下落+摆动+叶片自传。
& & & & &也就是只要将这三个动作实现,并同时执行就可以实现树叶飘落的效果。
下面就拿出代码具体解析实现过程:
老规矩,先上.h的内容,.h就不多解释了:
#ifndef&__LEAF_H__&&
#define&__LEAF_H__&&
#include&"cocos2d.h"&&
USING_NS_CC;&&
class&Leaf&:&public&cocos2d::CCLayer&&
&&&&virtual&bool&init();&&
&&&&void&resetLeafPos(CCNode*&sender);&&
&&&&void&playLeafAnim(CCSprite&*spriteLeaf);&&
&&&&LAYER_NODE_FUNC(Leaf);&&
#endif&//&__LEAF_H__&&
&& &&& &接下来是具体的实现,为了我们能不断的产生自然、随和的落叶,我们分三步来完成:
& & & & &&&1:第一次初始化;2:落叶动作的实现;3:下落动作完成重新设定落叶开始。
上代码,先看看用到的头文件:
#include&&iostream&&&
#include&&ctime&&&
#include&&cstdlib&&&
#include"Leaf.h"&&
using&namespace&&&
enum&{TAG_LEAF1&=&101,&TAG_LEAF2};&&
初始化树叶精灵的设定:
&span&style="font-size:12"&bool&Leaf::init()&&
&&&&CCSprite&*spriteLeaf1&=&CCSprite::spriteWithFile("img_yezi_1.png");&&
&&&&spriteLeaf1-&setRotation(30);&&
&&&&spriteLeaf1-&setAnchorPoint(ccp(0.5,&3));&&
&&&&spriteLeaf1-&setPosition(ccp(450,&500));&&
&&&&spriteLeaf1-&setScale(0.5);&&
&&&&this-&addChild(spriteLeaf1,100,TAG_LEAF1);&&
&&&&this-&playLeafAnim(spriteLeaf1);&&
&&&&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);&&
&&&&return&true;&&
}&/span&&&
& & & & & 将精灵的锚点设定在其高度的3倍的位置,加上旋转动作后,叶片会产生单摆的动作效果。再加上下落的动作,就会有树叶飘落的感觉了。
&span&style="font-size:12"&&&
void&Leaf::playLeafAnim(CCSprite&*spriteLeaf)&&
&&&&int&iTag&=&spriteLeaf-&getTag();&&
&&&&CCLog("playtag%d",&iTag);&&
&&&&ccTime&time,&roT&&
&&&&float&fAngle1,&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());&&
&&&&int&iRandPos&=&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);&&
&&&&CCOrbitCamera&*&orbit&=&CCOrbitCamera::actionWithDuration(8,&1,&0,&0,&360,&45,&0);&&
&&&&CCRepeat&*fz3d&=&CCRepeat::actionWithAction(orbit,&-1);&&
&&&&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));&&
}&/span&&&
& & & & &现在叶子飘落的主干就设定完毕了,其实看上去并不复杂,就是三个动作:下落+摆动+翻转,未来使落叶更自然,我们尽可能的在数据可变的范围内使用随机参数,我这里用了系统时间做种子来产生随机数,但是我感觉产生的随机数还是不够理想,如果你有更好的种子,可以告诉我。其实还有很多参数可以在限定范围内使用随机数,由于时间关系我没有逐个去调试,而是直接设定了一个固定值。有时间你可以逐个设定实验,找到最佳的数据范围。
& & & & &现在为了使我们的落叶能够源源不断的产生,我们还需要让落叶的产生和消亡循环起来:
&span&style="font-size:12"&&&
void&Leaf::resetLeafPos(CCNode*&sender)&&
&&&&int&iTag&=&int(sender-&getTag());&&
&&&&int&iZoder&=&int(sender-&getZOrder());&&
&&&&sender-&removeFromParentAndCleanup(true);&&
&&&&char&sImg[15]&=&"img_yezi_1.png";&&
&&&&_snprintf(sImg,&sizeof(sImg),&"img_yezi_%d.png",&iTag&%&100);&&
&&&&CCPoint&&&
&&&&float&fA&&
&&&&srand((UINT)GetCurrentTime());&&
&&&&int&iRand&=&(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);&&
}&/span&&&
& & & & & 这样3d仿真的落叶的效果就基本实现了,为了节约时间,这里只写了2片叶子的情况,多片叶子的情况可以举一反三,多加几片叶子就行。这里需要注意的是在使用CCOrbitCamera来实现三维空间的翻转时,由于openGL绘图的关系,我们得将精灵的深度设置上浮,以避免openGL绘图时精灵的部分被后面的色彩遮挡。
& & & & &解决遮挡问题可以直接关闭深度测试CCDirector::sharedDirector()-&setDepthTest(false);
& & & & &也可以设置精灵VertexZ上浮spriteLeaf-&setVertexZ(60);
& & & & &如果你的程序不需要深度测试,你大可以直接关了它,但是你不能确定是的程序是否每个地方都没有用到深度测试,所以,推荐设置VertexZ值来避免你的精灵被遮挡。VertexZ值的大小为你的精灵被挡住部分的像素值。
上一话题:
下一话题:
登录后才能评论,请先或。cocos2dx扩展CCAction实现精灵抛物线运动
时间: 21:24:11
&&&& 阅读:1522
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&  在不使用物理引擎的情况下,模拟物体在重力作用下的抛物线运动(忽略空气阻力)。给出运动起始点位置,终点位置,重力加速度g,起始点的发射角作为参数。
  先根据已知条件求出物体在x轴和y轴上的初速度,再根据公式f(t)=v0t+0.5*at2 &求出运动轨迹。
   类CCParabolaMove继承自CCAction。
1 CCParabolaMove* CCParabolaMove::create(const CCPoint& startPosition, const CCPoint& endPosition, float angle, float g,float &return_duration)
CCParabolaMove *pRet = new CCParabolaMove();
float vx0,vy0, x1, y1,
x1 = endPosition.x - startPosition.x;
y1 = endPosition.y - startPosition.y 8
x1 /= PIXELS_PER_METER; //像素到米的转换,PIXELS_PER_METER为转换系数,这里设置为100
y1 /= PIXELS_PER_METER;
angle = angle*3.14 / 180;//convert t to radian
angle *= -1;
vx0 = x1*sqrt(g / 2 / (x1*tan(angle) - y1)); //求出初速度
vy0 = vx0 * tan(angle);
duration = x1 / vx0; //求出整个运动的时间
return_duration = //将duration通过参数返回22
pRet-&initWithDuration(duration,startPosition, endPosition, angle,g, vx0, vy0);
pRet-&autorelease();
create()为静态函数,所以对非静态成员变量的赋值要在initWithDuration()中实现:
1 bool CCParabolaMove::initWithDuration(float duration, const CCPoint& startPosition, const CCPoint& endPosition, float angle, float g, float vx0, float vy0)
if (CCActionInterval::initWithDuration(duration))
m_vx0 = vx0;
m_vy0 = vy0;
m_startPosition = startP
m_endPosition = endP
angle = angle*3.14 / 180;//convert t to radian
m_tan_a = tan(angle);
return true;
return false;
在runaction时startWithTarget(CCNode *pTarget)会首先被调用,通过pTarget为执行动作的对象指针:
1 void CCParabolaMove::startWithTarget(CCNode *pTarget)
CCActionInterval::startWithTarget(pTarget);
update(float t)中参数t表示当前运动时间与整个运动时长的比值,范围0到1。
1 void CCParabolaMove::update(float t)
if (m_pTarget)
float elapsed = t * m_fD //获得当前的运动时间
float diff_x = m_vx0 *
float diff_y = m_vy0 * elapsed - 0.5 * m_g * elapsed *
CCPoint newPos = ccpAdd(m_startPosition, ccp(diff_x * PIXELS_PER_METER, diff_y * PIXELS_PER_METER)); //单位由米转换为像素
m_pTarget-&setPosition(newPos);
&标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:/codingdiary/p/4133617.html
教程昨日排行
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!热门栏目:
其他城市:
幼儿园资讯:
幼儿园资源:
健康宝贝:
时尚妈咪:
美食厨房:
您现在的位置: &
中班体育教案:运动小精灵
来源:网络
  一、活动目标:
  1.学习阅读指示牌。
  2.根据指示做动作。
  二、活动准备:
  自制有趣的指示牌。
  三、活动过程:
  1.事先与幼儿讨论幼儿园的运动设备,并为它们命名。
  2.来到幼儿园的操场,向幼儿说明游戏规则及摆放好指示牌。
  3.选首儿歌或童谣,让幼儿在歌声中按照指示牌方向准备出发。如到&圆圆国&拿起呼啦圈在地上或身上转一下、用单脚跳到&百花国&闻闻花香、走到&石头国&抱抱石头看有多大、&滑梯国&里可溜滑梯、再到&洞洞国&穿过拱桥、&绳子国&是跳5次绳才算通过、&昆虫国&则要学一种昆虫的动作。回到目的地时,便成为&快乐国&里的精灵了。
  四、活动建议:
  1.可选择户外或幼儿园里适当的地方,自己制作指示牌。
  3. 若因雨天无法进行,也可在教室中进行此活动。
欢迎使用手机、平板等移动设备访问幼教网,幼儿教育我们一路陪伴同行!
点击查看更多
幼升小新闻Pages: 1/2
主题 : 如何实现精灵在指定范围内的随机运动
级别: 新手上路
UID: 420797
可可豆: 96 CB
威望: 83 点
在线时间: 85(时)
发自: Web Page
来源于&&分类
如何实现精灵在指定范围内的随机运动&&&
cocos2dx-3.x如题,在TMX中圈定一个范围,                //出现指定区域随机位置        int minY = 3050;        int maxY = 3350;        int rangeY = maxY - minY;        int actualY = rand() % rangeY + minY;        int minX = 1000;        int maxX = 1400;        int rangeX = maxX - minX;        int actualX = rand() % rangeX + minX;        monster-&setPosition(Vec2(actualX, actualY));随机出现后如何让精灵随机运动[ 此帖被abc8-02-05 11:06重新编辑 ]
级别: 圣骑士
UID: 356822
可可豆: 790 CB
威望: 775 点
在线时间: 438(时)
发自: Web Page
X,Y在指定范围内随机,随机出来后,用MoveTo动作,使用回调函数,当动作执行结束后继续随机,执行动作
级别: 新手上路
UID: 420797
可可豆: 96 CB
威望: 83 点
在线时间: 85(时)
发自: Web Page
回 1楼(abc88798) 的帖子
怎么进行继续随机呢,现在只能移动一下,随机出来的值不会变??&&&&&&&&&&&&&&&&int minb = 3350;&&&&&&&&int maxb = 3550;&&&&&&&&int rangeb = maxb -&&&&&&&&int actualb = rand() % rangeb +&&&&&&&&int mina = 4400;&&&&&&&&int maxa = 4800;&&&&&&&&int rangea = maxa -&&&&&&&&int actuala = rand() % rangea +&&&&&&&&&&&&&&&&auto yidong = MoveTo::create(5.0f, Vec2(actuala, actualb));&&&&&&&&auto seq = Sequence::create(yidong, yidong, NULL);&&&&&&&&&&&&&&&& monster-&runAction(seq);
级别: 侠客
UID: 283521
可可豆: 489 CB
威望: 462 点
在线时间: 2173(时)
发自: Web Page
回 2楼(azxkoop) 的帖子
Sequence最后放一个callfuntion, 回调你上面的函数
临风振羽,知青云之志未消
级别: 圣骑士
UID: 356822
可可豆: 790 CB
威望: 775 点
在线时间: 438(时)
发自: Web Page
回 2楼(azxkoop) 的帖子
楼上正解,callfuntion就是我说的回调函数
级别: 新手上路
UID: 420797
可可豆: 96 CB
威望: 83 点
在线时间: 85(时)
发自: Web Page
回 3楼(紫色阔叶林) 的帖子
monster-&yidong();void StrongAndSlowMonster::yidong(){&&&&auto yd = MoveTo::create(5.0f, Vec2(actuala, actualb));&&&&auto seq = Sequence::create(yd, &&&&&&&&CallFuncN::create(CC_CALLBACK_0(StrongAndSlowMonster::yidong, this)),&&&&&&&&NULL);&&&&runAction(seq);}运行的结果是精灵闪一下就不见了.......如何解决
级别: 新手上路
UID: 420797
可可豆: 96 CB
威望: 83 点
在线时间: 85(时)
发自: Web Page
回 4楼(abc88798) 的帖子
求教5L解决办法
级别: 圣骑士
UID: 356822
可可豆: 790 CB
威望: 775 点
在线时间: 438(时)
发自: Web Page
回 6楼(azxkoop) 的帖子
楼主基本的概念都没搞懂..下面这段代码&&&&&&&&auto yidong = MoveTo::create(5.0f, Vec2(actuala, actualb));&&&&&&&&auto seq = Sequence::create(yidong, yidong, NULL);里面第二句代码,就跟我告诉你,你先回家,回到家后你再回家...你第二次肯定就不动了..因为我叫你去得时同个目的&&&&auto yd = MoveTo::create(5.0f, Vec2(actuala, actualb));Vec2(actuala, actualb)这是你要到达的点,值在哪里改变?和之前一样的错误...楼主至少应该要懂得这个函数有什么用,里面每个参数干嘛的。建议楼主先去查下每个函数和参数干嘛的,然后再自己整理下逻辑写下
级别: 侠客
UID: 283521
可可豆: 489 CB
威望: 462 点
在线时间: 2173(时)
发自: Web Page
回 5楼(azxkoop) 的帖子
你把真实代码贴上来吧,你上面那样,有些我不知道是你故意省略的还是你真这么写的,譬如“runAction(seq);”我不知道是你真没加上monster-&runAction(seq); 还是怎么样
void Test::randMove()
    float positionX = CCRANDOM_0_1() * 200;
    float positionY = CCRANDOM_0_1() * 200;
    CCMoveTo* yd = CCMoveTo::create(5.0f, ccp(positionX, positionY));
    CCSequence* seq = CCSequence::create(yd, CCCallFunc::create(this, callfunc_selector(Test::randMove)), NULL);
    testSprite-&runAction(seq);
void Test::darwMainScence()
    testSprite = CCSprite::create(test.png&);
    this-&addChild(testSprite, 100);
    testSprite-&setPosition(ccp(100,100));
    randMove();
我刚自己写了份是可以的,当然我用的是2.X的引擎
临风振羽,知青云之志未消
级别: 新手上路
可可豆: 48 CB
威望: 48 点
在线时间: 38(时)
发自: Web Page
可以用RepeatForever这个action试试,感觉效果更好Repeat/RepeatForever反复执行某个动作,通常我们用Repeat和RepeatForever这两个方法执行:Repeat::create(FiniteTimeAction *action, unsigned int times);RepeatForever::create(ActionInterval *action);
Pages: 1/2
关注本帖(如果有新回复会站内信通知您)
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 关注CVP公众号
扫一扫 浏览移动版

我要回帖

更多关于 js 指定范围随机数 的文章

 

随机推荐