cocos2d 物理平抛,斜抛运动
1. 效果图
需求是这样的,这个bug有一个起始的位置,然后会给一个终点的位置,希望bug 以一种跳跃的物理方式来运动到终点。
CCSprite* ghost = CCSprite::create("ghost.png");this->addChild(ghost, 2);ghost->setPosition(ccp(100, 100));ghost->setScaleX(-1);
ghost->runAction(GhostMoveAction::create(700, 3000, ghost->getPosition(), ccp(300, 200)));
2. 一些数学公式
因为终点位置是固定的,所以,就没考虑使用物理引擎了。打算手动实现。
物理中的平抛运动的公式是这样的:
参考下面的地址
http://wenku.baidu.com/link?url=nrGU1314OUvAccKEDCeslVuK1Ow3KUpGCeYUpyJhzQYLXxeH4Eg66QBqKL5fEoW73VzrnfpXDSVIU4EivGTqtTslrNHJq6MM1A_5xDTHMKC
要提下就是cocos2d中的action里面的update方法,是每一帧都在设置精灵的位置,最终得到精灵运动的效果。所以我们要根据物体的水平速度,重力加速度,以及起点和终点, 算出,物体在t时间的位置。
1. 水平的X位置比较好算,就是Vx*t, 注意这里的t是总共运动的时间, 而cocos2d中actoin的update 中的t 的范围是【0-1】, 并不是总的运动时间,所以cocos2d中设置x的位置是 Vx * t * totalTimeX, 因为t * 总时间的范围就是 [0- totalTimeX]了。
2. 垂直方向上的位置,是Vy*t - 0.5 * g * t * t, 这里的t 同样是总的运动时间, 所以在cocos2d 中是 Vy*t* totalTimeY - 0.5 * g * t * totalTimeY * t * totalTimeY
查看上面1中的公式,我们发现totalTimeX即,水平上的运行时间是可以算出来的,因为我们知道起始位置和终点位置,还知道水平上的速度。那么TotalTimeX = abs(endPosition.x - startPosition.x) / v;
而上面2中的公式比较复杂些, 垂直方向上的速度不知道,垂直运行的总时间也不知道。
由 Y = Vy * t - 0.5 * g * t * t 得出 Vy = (Y + 0.5 * g * t * t) / t, 因为我们知道垂直运动的时间跟水平运动的时间是一样的,另外我们也知道垂直运动的距离,所以就可以得到垂直方向上的速度了。得到垂直的速度,带入2中,就可以得到精灵每一帧的位置了。
3. 具体代码
注意是cocos2d 2.2.6的,3.X的类似修改下就可以。
GhostMoveAction.h
#include "cocos2d.h"
#include "actions/CCActionInterval.h"USING_NS_CC;//抛物线运动,输入,水平速度和重力加速度,还有开始位置和终点位置,物体会以抛物线的方式从开始位置运动到终止位置
//testSprite->runAction(GhostMoveAction::create(700, 3000, testSprite->getPosition(), endPos));
class GhostMoveAction : public CCActionInterval
{
public: GhostMoveAction(void);~GhostMoveAction(void);// v 是水平的速度, g是重力加速度, startPosition 是物体开始位置, endPosition是物体终点位置static GhostMoveAction* create(float v, float g, const CCPoint& startPosition, const CCPoint& endPosition);virtual void update(float t);//不支持virtual CCObject* copyWithZone(CCZone* pZone);//不支持virtual void startWithTarget(CCNode *pTarget);//不支持virtual CCActionInterval* reverse(void);
private:CCPoint mStartPos;CCPoint mEndPos;//X 轴方向移动的时间float mXDuration;//Y 轴方向移动的时间float mYDuration;//水平的速度float mV;//重力加速度float mG;//初始向上的速度float mYV;
};
GhostMoveAction.cpp
#include "GhostMoveAction.h"CCObject* GhostMoveAction::copyWithZone(CCZone* pZone){return NULL;}void GhostMoveAction::startWithTarget(CCNode *pTarget){CCActionInterval::startWithTarget(pTarget);mStartPos = pTarget->getPosition();}CCActionInterval* GhostMoveAction::reverse(void){return NULL;}GhostMoveAction::GhostMoveAction(void){}
GhostMoveAction::~GhostMoveAction(void){}GhostMoveAction* GhostMoveAction::create(float v, float g, const CCPoint& startPosition, const CCPoint& endPosition){GhostMoveAction *pRet = new GhostMoveAction();pRet->mG = g;pRet->mStartPos = startPosition;pRet->mEndPos = endPosition;pRet->mV = v;pRet->mXDuration = abs(endPosition.x - startPosition.x) / v;pRet->mYDuration = pRet->mXDuration;if(pRet->mYDuration <= 0.5f){//pRet->mYDuration = abs(endPosition.y - startPosition.y) / 20.0f;pRet->mYDuration = 0.5f;}//由 Y = V * t - 0.5 * g * t * t 得出 V = (Y + 0.5 * g * t * t) / tpRet->mYV = ((endPosition.y - startPosition.y) + 0.5f * pRet->mG * pRet->mYDuration * pRet->mYDuration) / pRet->mYDuration;pRet->initWithDuration(pRet->mXDuration >= pRet->mYDuration ? pRet->mXDuration : pRet->mYDuration);pRet->autorelease();return pRet;
}void GhostMoveAction::update(float t)
{// t 的范围是 [0, 1]//所以 mXDuration * t 才是总的运动时间 [0, mXDuration]if (m_pTarget){// 水平的位置就是 X = V * tif(mStartPos.x < mEndPos.x){m_pTarget->setPositionX(mStartPos.x + t * mXDuration * mV);}else{m_pTarget->setPositionX(mStartPos.x - t * mXDuration * mV);} // Y = V * t - 0.5 * g * t * tm_pTarget->setPositionY(mStartPos.y + (mYV * (t * mYDuration) - 0.5f * mG * (t * mYDuration) * (t * mYDuration)));}
}
一般情况下Y上面的运动时间是跟X上面的运动时间是一样的,但是有时候x距离很短,但是y距离长,就会运动太快,这里加了最小0.5,还有要注意到重力加速度并不是10,这个要自己调,看起来自然点就可以,文中用的是3000.
4. 游戏效果
http://www.waitingfy.com/archives/1798
cocos2d 物理平抛,斜抛运动相关推荐
- matlab模拟斜抛运动60,大学物理教学改革论文,关于大学物理教学方法改革-Matlab的妙用相关参考文献资料-免费论文范文...
导读:本文是一篇关于大学物理教学改革论文范文,可作为相关选题参考,和写作参考文献. (1.长江师范学院大学物理教研室 重庆 408100, 2.内蒙古工业大学 理学院物理系 内蒙古呼和浩特 01005 ...
- Python + matplotlib.animation 模拟斜抛运动动画(含完整代码)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 Abstract Introduction Matplotlib.animation Physics model and C ...
- 三维场景中斜抛运动顶点的生成
三维场景中斜抛运动顶点的生成 1 算法思想-斜抛运动 2 代码 3 参考文献 1 算法思想-斜抛运动 2 代码 void getparabola_vertex_2(glm::vec3 _Point, ...
- matlab 斜抛 空气阻力,运用MATLAB对运动学、动力学问题进行过程分析
第 29 卷第 6 期 Vol. 29 NO. 6 重庆工商大学学报( 自然科学版) J Chongqing Technol Business Univ. ( Nat Sci Ed) 2012 年 6 ...
- 向量表示 运动抛物线_初学讲义之高中物理(四)常见运动类型
本章主要介绍几种较为常见的运动模型以及处理思路 一.抛物运动 抛物运动是一种较为简单的运动模型,在现实生活中非常常见,比如向空中抛球.向河里丢石子,等等.根据抛出方向的不同,抛物运动可以分为竖抛运动. ...
- 想抛就抛:Application_Error中统一处理ajax请求执行中抛出的异常
想抛就抛:Application_Error中统一处理ajax请求执行中抛出的异常 参考文章: (1)想抛就抛:Application_Error中统一处理ajax请求执行中抛出的异常 (2)http ...
- 麦克纳姆轮斜向运动奥秘的根源
关注同名微信公众号"混沌无形",有趣好文! 原文链接:https://mp.weixin.qq.com/s/GWhlXsuY6QYyoZydaSYpjQ(包含原文PDF百度云下载链 ...
- 疯狂坦克高抛,半抛,小抛算法
所有车的高抛半抛及小抛算法 17:等待和数字中间 18:百位数字前端 19:百位数字 20:十位和个位数字中间 21:数字框最后 22:喇叭框开头 23:喇叭把手前一点(23.5这个位置即为老土半抛和 ...
- C语言编码小球斜抛运动,利用C4droid绘制小球斜抛运动轨迹(考虑空气阻力)
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 我把源代码分享出来,欢迎有兴趣的朋友下载测试,修改优化. /*********************************************** ...
- 斜抛运动的最远射程问题
问题概述: 在o点上方高度为h处以速度v抛出一物体,该物体运动一段时间后落到地面p处,问抛出方向与水平方向的夹角是多少时,op有最大值,最大值是多少? 当 时: op有最大值: 题目:迎风舞
最新文章
- linux mariadb
- python walk_Python os.walk()方法
- prepare 和 row_count()一起使用的误区
- oracle 加密怎么解密,oracle加密encrypt,解密decrypt,
- 简单的绑定数据截取时间字符年月日
- 注册表把html设置成桌面,[注册表] 将Windows 10默认应用程序设置页面添加到桌面右键菜单中...
- oracle 删除函数对象不存在_Python 函数式编程指北,不只是面向对象哦
- BI的价值体现在哪里
- WordPress 简约大气昼夜免费导航-NDNAV主题
- 你来比划我来猜 绿色游戏猜词小软件
- 12款免费的桌面便签软件
- 数学之美 第三版 目录
- 隔段时间网络就会变差,重启路由器恢复,这是为什么
- zoj 3551 Bloodsucker (概率dp)
- 2008年12月12号,星期五晴。为人父,却不能尽父责,为人夫,却不能尽夫责。这种痛楚什么时候才能结束。
- mysql group by 之后取每个分组最新的一条(或者按照自定义的规则排序)
- 苹果手机越狱软件_俄罗斯要求 iPhone 预装本国软件,苹果称等同于越狱无法接受...
- 想考阿里云ACE需要做什么准备?考下来难不难?
- 自然语言处理之hmm(隐马尔可夫模型)
- SpringBoot项目的两种打包方式分析