转自:http://blog.csdn.net/ufolr/article/details/7447773

在cocos2d中,系统提供了CCMove、CCJump、CCBezier(贝塞尔曲线)等让精灵移动的action,但是有时候,为了让程序看上不不是那么的呆板,或者为了实现某些特定的功能,我们需要让精灵按照我们自己设定的路径(曲线运动)来移动。这就是这位篇文章我们需要讨论的话题。

自己开始也很纠结cocos2dx没有提供更多的action动作,比如说我们要做个抛物线什么的,虽然可以用贝塞尔曲线来模拟。

用贝塞尔曲线扔个飞镖什么的倒是还不错,但当你需要重复执行action时,问题就出来了,再第二次重复贝塞尔曲线动作到时候,精灵就会飞到别的地方去了。(出现这个问题的原因,猜测贝塞尔曲线是没有起点和终点了,在第一次执行了动作之后,之前的曲线动作并没有被释放,第二次再延续这个动作,就会延为执行的那段曲线移动,当然,只是猜测,未深入研究。后来觉得不是这个原因,但具体原因未明。)

如果我们要做一个椭圆的轨迹,有人说用3~4条贝塞尔曲线来模拟,但实验证明,在两天贝塞尔曲线的衔接点Action会有停顿,所以效果简直可以用鲁迅先生的“目不忍视”来形容。

于是,我们考虑自己定义曲线的路径,让精灵按照我们自己的定义来行动。

需求:

将自己设定的路径封装成一个action,让精灵执行,这里以椭圆轨迹为例。

先来两张效果图:

实现:

单独建一个自己的动作模块:LRActionInterval。{LRActionInterval.h&LRActionInterval.cpp}

基于cocos2d-x的CCActionInterval来封装自己的动作,所以:

LRActionInterval.h

  1. #include "CCActionInterval.h"//包含系统延时类动作头文件
  2.  
  3. using namespace cocos2d;

想一想确定一个椭圆的条件,初中老师告诉我们,去顶一个椭圆我们需要知道他的空间位置(中心点坐标)、长半轴(a)、和短半轴(b)(或者知道半焦距(c))。也就是我们需要三个量来确定一个椭圆,所以在LRActionInterval.h中定义一个包含三个成员的结构来作为我们生成椭圆的参数:

  1. // 定义一个结构来包含确定椭圆的参数
  2. typedef struct _lrTuoyuanConfig {
  3. //中心点坐标
  4. CCPoint centerPosition;
  5. //椭圆a长,三角斜边
  6. float aLength;
  7. //椭圆c长,三角底边
  8. float cLength;
  9. } lrTuoyuanConfig;

然后定义我们的椭圆的类:

  1. class __declspec(dllexport) LRTuoyuanBy : public CCActionInterval
  2. {
  3. public:
  4. //用“动作持续时间”和“椭圆控制参数”初始化动作
  5. bool initWithDuration(ccTime t, const lrTuoyuanConfig& c);
  6. virtual void update(ccTime time);//利用update函数来不断的设定坐标
  7. public:
  8. //用“动作持续时间”和“椭圆控制参数”创建动作
  9. static LRTuoyuanBy *actionWithDuration(ccTime t, const lrTuoyuanConfig& c);
  10.  
  11. protected:
  12. lrTuoyuanConfig m_sConfig;
  13. CCPoint m_startPosition;
  14. CCPoint s_startPosition;
  15. };

接下来是我们的实现部分:

LRActionInterval.cpp

其实设定路径就是不断的刷新,将路径上的点赋给执行action的对象。

因此,既然我们要做一个椭圆的轨迹,我们就需要得到椭圆上每个点的坐标值,然后将其赋给执行action的对象。获得椭圆的轨迹,再次回想初中老师的教导——椭圆标准方程:x^2/a+y^2/b=1。

但这是个2次方程,李勇这个方程求x、y的值的时候会需要开方,而开方后还需要确定正负,虽然可以实现功能,但是给自己增加了不少代码量,也会浪费不少笔芯。所以我们要找一个更简单的公式——椭圆参数方程。

参数方程:x=acos(θ)y=bsin(θ);利用这个一次方程可以直观的计算出当前坐标点。

由椭圆的参数方程我们可以分别写出返回X/Y坐标值的函数:

  1. static inline float tuoyuanXat( float a, float bx, float c, ccTime t )//返回X坐标
  2. {
  3. //参数方程
  4. return -a*cos(*3.1415926*t)+a;
  5. }
  6. static inline float tuoyuanYat( float a, float by, float c, ccTime t )//返回Y坐标
  7. {
  8. float b = sqrt(powf(a, ) - powf(c, ));//因为之前定义的参数是焦距c而不是短半轴b,所以需要计算出b
  9. //参数方程
  10. return b*sin(*3.1415926*t);
  11. }

然后实现根据中心左边、a、c确定椭圆:

  1. //
  2. //TuoyuanBy
  3. //
  4. LRTuoyuanBy* LRTuoyuanBy::actionWithDuration(ccTime t, const lrTuoyuanConfig& c)//利用之前定义的椭圆的三个参数初始化椭圆
  5. {
  6. LRTuoyuanBy *pTuoyuanBy = new LRTuoyuanBy();
  7. pTuoyuanBy->initWithDuration(t, c);
  8. pTuoyuanBy->autorelease();
  9.  
  10. return pTuoyuanBy;
  11. }
  12.  
  13. bool LRTuoyuanBy::initWithDuration(ccTime t, const lrTuoyuanConfig& c)
  14. {
  15. if (CCActionInterval::initWithDuration(t))
  16. {
  17. m_sConfig = c;
  18. return true;
  19. }
  20.  
  21. return false;
  22. }
  23. void LRTuoyuanBy::update(ccTime time)
  24. {
  25. if (m_pTarget)
  26. {
  27. CCPoint s_startPosition =m_sConfig.centerPosition;//中心点坐标
  28. float a = m_sConfig.aLength;
  29. float bx = m_sConfig.centerPosition.x;
  30. float by = m_sConfig.centerPosition.y;
  31. float c = m_sConfig.cLength;
  32. float x = tuoyuanXat(a, bx, c, time);//调用之前的坐标计算函数来计算出坐标值
  33. float y = tuoyuanYat(a, by, c, time);
  34. m_pTarget->setPosition(ccpAdd(s_startPosition, ccp(x-a, y)));//由于我们画计算出的椭圆你做值是以原点为中心的,所以需要加上我们设定的中心点坐标
  35. }
  36. }

这样我们只需要在程序中像使用CCBezier一样使用LRTuoyuan,让精灵执行这个Action,他就会沿着我们设定的椭圆运动了。当然,只要你给出你自己的运动函数轨迹,精灵就会按照你自己设定的轨迹运动。

cocos2d-x 让精灵按照自己设定的运动轨迹行动的更多相关文章

  1. cocos2d心得关于精灵帧缓存

    在cocos2d中,精灵帧缓存CCSpriteFrameCache是用来存储精灵帧的.它没有特别的属性,只存储了一些用来管理CCSpriteFrame的方法. 以一个例子来说明,一般在又纹理图集的程序 ...

  2. COCOS2D中对精灵的操作、对图片的各种操作

    内容简要: 1.初始化 2.创建无图的精灵 3.设置精灵贴图大小  4.添加入层中 5.对精灵进行缩放  6.对精灵宽或高进行缩放  7.旋转精灵 8.设置精灵透明度  9.精灵的镜像反转  10.设 ...

  3. cocos2d-x 3.0 导演,场景,层,精灵

    导演(Director) 一款游戏好比一部电影,只是游戏具有更强的交互性,不过它们的基本原理是一致的.所以在Cocos2dx中把统筹游戏大局的类抽象为导演(Director),Director是整个c ...

  4. 【Cocos2D研究院之游戏开发】

    http://www.xuanyusong.com/archives/category/ios/cocos2d_game 分类目录归档:[Cocos2D研究院之游戏开发]   201211-19 Co ...

  5. Cocos2d-x 的“HelloWorld” 深入分析

    本节所用Cocos2d-x版本:cocos2d-1.0.1-x-0.12.0 不能免俗,一切都从“HelloWorld!”开始.打开HelloWorld工程,里面有两个文件目录Classes和win3 ...

  6. 长平狐 Cocos2d-x 的“HelloWorld” 深入分析

                              Cocos2d-x 的“HelloWorld” 深入分析 本节所用Cocos2d-x版本:cocos2d-1.0.1-x-0.12.0 不能免俗,一 ...

  7. Cocos引擎开发者指南(1-5)

    Cocos引擎开发者指南 英文原版:http://www.cocos2d-x.org/docs/programmers-guide/1/ 中午翻译:http://www.cocos.com/doc/t ...

  8. cocos基础教程(4)基础概念介绍

    在Cocos2d-x-3.x引擎中,采用节点树形结构来管理游戏对象,一个游戏可以划分为不同的场景,一个场景又可以分为不同的层,一个层又可以拥有任意个可见的游戏节点(即对象,游戏中基本上所有的类都派生于 ...

  9. 【Cocos2D-x 3.5实战】坦克大战(2)游戏开始界面

    关于游戏的素材都是在网上到处搜集到的,然后自己再用二流的ps技术修修改改的,所以有可能混在一起有点不搭调(没有办法啊,没有美工Orz.. 项目已经建立好了,然后我们需要把我们下载的素材放到Resour ...

随机推荐

  1. apache开源项目 --Struts

    struts简介 Struts是Apache软件基金会(ASF)赞助的一个开源项目.它最初是jakarta项目中的一个子项目,并在2004年3月成为ASF的顶级项目.它通过采用JavaServlet/ ...

  2. 开发ffmpeg/live555常见问题错误及解决方法

    #include <iostream>using namespace std;extern "C" {#include <libavcodec/avcodec.h ...

  3. hdu 1299 Diophantus of Alexandria

    1/x + 1/y = 1/n 1<=n<=10^9给你 n 求符合要求的x,y有多少对 x<=y// 首先 x>n 那么设 x=n+m 那么 1/y= 1/n - 1/(n+ ...

  4. 锋利的jQuery读书笔记---jQuery中操作DOM

    一般来说,DOM的操作分为3个方面,即DOM Core.HTML-DOM和CSS-DOM jQuery中的DOM操作主要包括以下种类: 查找节点 查找元素节点 查找属性节点 创建节点 创建元素节点 创 ...

  5. SharePoint 2010 列表项事件接收器 ItemAdded 的使用方法

    列表项事件处理器是继承于Microsoft.SharePoint.SPItemEventReceiver的类,Microsoft.SharePoint.SPItemEventReceiver类提供了许 ...

  6. POJ 1860 Currency Exchange

    题意:有n种货币,可以互相兑换,有m个兑换规则,兑换规则给出汇率r和手续费c,公式为b = (a - c) * r,从a货币兑换为b货币,问能不能通过不断的兑换赚钱,兑换期间手中的钱数不可以为负. 解 ...

  7. KVO KVC

    @interface FoodData : NSObject { NSString * foodName; float foodPrice; } @end ////////////////////// ...

  8. bzoj 3365 [Usaco2004 Feb]Distance Statistics 路程统计(点分治,单调)

    [题意] 求树上长度不超过k的点对数目. [思路] 和 Tree 一样一样的. 就是最后统计的时候别忘把根加上. [代码] #include<set> #include<cmath& ...

  9. 题目1434:今年暑假不AC (项目安排类:结束时间快排,判断开始时间)

    题目描述: “今年暑假不AC?”“是的.”“那你干什么呢?”“看世界杯呀,笨蛋!”“@#$%^&*%...”确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会抛开电脑,奔向电视作为 ...

  10. ACM2033

    /**人见人爱A+B Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Su ...