• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

chchpd

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

cocos2dx --- Action综合应用二:椭圆运动Action

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

   cocos2dx中提供了一些常用的action,但有时为了实现某种特效,需要定义自己的Action。这篇博文展现了通过继承CCActionInterval实现了椭圆运动Action。大家可以根据ufolr博主的思想,举一反三实现自己的Action。

      思路:根据椭圆方程(在实现当中尽量用参数方程,避免复杂平方的计算), 在每一帧中更新Sprite的位置

    实现:确定一个椭圆的条件,需要知道空间位置(中心点坐标)、长半轴(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;

定义椭圆Action类

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

其实设定路径就是不断的刷新,将路径上的点赋给执行action的对象。因此,既然需要做一个椭圆的轨迹,就需要得到椭圆上每个点的坐标值,然后将其赋给执行action的对象。 参数方程:x=acos(θ),y=bsin(θ);利用这个一次方程可以直观的计算出当前坐标点。由椭圆的参数方程可以分别写出返回X/Y坐标值的函数:

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

然后根据中心、a、c确定椭圆:

 1 //
 2 //TuoyuanBy
 3 //
 4 LRTuoyuanBy* LRTuoyuanBy::actionWithDuration(float 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(float 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(float 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 }

 

 

 

posted on 2013-05-07 17:04  chchpd  阅读(1068)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3