cocos2d-x学习笔记(三)让精灵按照自己设定的运动轨迹行动(曲线移动)。(以椭圆轨迹为例)。
2012-12-09 21:38
549 查看
cocos2d-x学习笔记(三)让精灵按照自己设定的运动轨迹行动(曲线移动)。(以椭圆轨迹为例)。
分类:
cocos2d-x2012-12-09 21:38373人阅读评论(0)收藏举报
ufolr原创,转载请注明:
转载自ufolr的博客 原文连接: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
[cpp]
view plaincopyprint?
#include "CCActionInterval.h"//包含系统延时类动作头文件
using
namespace cocos2d;
想一想确定一个椭圆的条件,初中老师告诉我们,去顶一个椭圆我们需要知道他的空间位置(中心点坐标)、长半轴(a)、和短半轴(b)(或者知道半焦距(c))。也就是我们需要三个量来确定一个椭圆,所以在LRActionInterval.h中定义一个包含三个成员的结构来作为我们生成椭圆的参数:
[cpp]
view plaincopyprint?
// 定义一个结构来包含确定椭圆的参数
typedef
struct _lrTuoyuanConfig {
//中心点坐标
CCPoint centerPosition;
//椭圆a长,三角斜边
float aLength;
//椭圆c长,三角底边
float cLength;
} lrTuoyuanConfig;
然后定义我们的椭圆的类:
[cpp]
view plaincopyprint?
class
__declspec(dllexport)
LRTuoyuanBy : public CCActionInterval
{
public:
//用“动作持续时间”和“椭圆控制参数”初始化动作
bool initWithDuration(ccTime t,
const lrTuoyuanConfig& c);
virtual
void update(ccTime time);//利用update函数来不断的设定坐标
public:
//用“动作持续时间”和“椭圆控制参数”创建动作
static LRTuoyuanBy *actionWithDuration(ccTime t,
const lrTuoyuanConfig& c);
protected:
lrTuoyuanConfig m_sConfig;
CCPoint m_startPosition;
CCPoint s_startPosition;
};
接下来是我们的实现部分:
LRActionInterval.cpp
其实设定路径就是不断的刷新,将路径上的点赋给执行action的对象。
因此,既然我们要做一个椭圆的轨迹,我们就需要得到椭圆上每个点的坐标值,然后将其赋给执行action的对象。获得椭圆的轨迹,再次回想初中老师的教导——椭圆标准方程:x^2/a+y^2/b=1。
但这是个2次方程,李勇这个方程求x、y的值的时候会需要开方,而开方后还需要确定正负,虽然可以实现功能,但是给自己增加了不少代码量,也会浪费不少笔芯。所以我们要找一个更简单的公式——椭圆参数方程。
参数方程:x=acos(θ)y=bsin(θ);利用这个一次方程可以直观的计算出当前坐标点。
由椭圆的参数方程我们可以分别写出返回X/Y坐标值的函数:
[cpp]
view plaincopyprint?
static
inline
float tuoyuanXat(
float a,
float bx,
float c, ccTime t )//返回X坐标
{
//参数方程
return -a*cos(2*3.1415926*t)+a;
}
static
inline
float tuoyuanYat(
float a,
float by,
float c, ccTime t )//返回Y坐标
{
float b = sqrt(powf(a, 2) - powf(c, 2));//因为之前定义的参数是焦距c而不是短半轴b,所以需要计算出b
//参数方程
return b*sin(2*3.1415926*t);
}
然后实现根据中心左边、a、c确定椭圆:
[cpp]
view plaincopyprint?
//
//TuoyuanBy
//
LRTuoyuanBy* LRTuoyuanBy::actionWithDuration(ccTime t,
const lrTuoyuanConfig& c)//利用之前定义的椭圆的三个参数初始化椭圆
{
LRTuoyuanBy *pTuoyuanBy =
new LRTuoyuanBy();
pTuoyuanBy->initWithDuration(t, c);
pTuoyuanBy->autorelease();
return pTuoyuanBy;
}
bool
LRTuoyuanBy::initWithDuration(ccTime t, const lrTuoyuanConfig&
c)
{
if (CCActionInterval::initWithDuration(t))
{
m_sConfig = c;
return
true;
}
return
false;
}
void
LRTuoyuanBy::update(ccTime time)
{
if (m_pTarget)
{
CCPoint s_startPosition =m_sConfig.centerPosition;//中心点坐标
float a = m_sConfig.aLength;
float bx = m_sConfig.centerPosition.x;
float by = m_sConfig.centerPosition.y;
float c = m_sConfig.cLength;
float x = tuoyuanXat(a, bx, c, time);//调用之前的坐标计算函数来计算出坐标值
float y = tuoyuanYat(a, by, c, time);
m_pTarget->setPosition(ccpAdd(s_startPosition, ccp(x-a, y)));//由于我们画计算出的椭圆你做值是以原点为中心的,所以需要加上我们设定的中心点坐标
}
}
这样我们只需要在程序中像使用CCBezier一样使用LRTuoyuan,让精灵执行这个Action,他就会沿着我们设定的椭圆运动了。当然,只要你给出你自己的运动函数轨迹,精灵就会按照你自己设定的轨迹运动。
分类:
cocos2d-x2012-12-09 21:38373人阅读评论(0)收藏举报
ufolr原创,转载请注明:
转载自ufolr的博客 原文连接: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
[cpp]
view plaincopyprint?
#include "CCActionInterval.h"//包含系统延时类动作头文件
using
namespace cocos2d;
想一想确定一个椭圆的条件,初中老师告诉我们,去顶一个椭圆我们需要知道他的空间位置(中心点坐标)、长半轴(a)、和短半轴(b)(或者知道半焦距(c))。也就是我们需要三个量来确定一个椭圆,所以在LRActionInterval.h中定义一个包含三个成员的结构来作为我们生成椭圆的参数:
[cpp]
view plaincopyprint?
// 定义一个结构来包含确定椭圆的参数
typedef
struct _lrTuoyuanConfig {
//中心点坐标
CCPoint centerPosition;
//椭圆a长,三角斜边
float aLength;
//椭圆c长,三角底边
float cLength;
} lrTuoyuanConfig;
然后定义我们的椭圆的类:
[cpp]
view plaincopyprint?
class
__declspec(dllexport)
LRTuoyuanBy : public CCActionInterval
{
public:
//用“动作持续时间”和“椭圆控制参数”初始化动作
bool initWithDuration(ccTime t,
const lrTuoyuanConfig& c);
virtual
void update(ccTime time);//利用update函数来不断的设定坐标
public:
//用“动作持续时间”和“椭圆控制参数”创建动作
static LRTuoyuanBy *actionWithDuration(ccTime t,
const lrTuoyuanConfig& c);
protected:
lrTuoyuanConfig m_sConfig;
CCPoint m_startPosition;
CCPoint s_startPosition;
};
接下来是我们的实现部分:
LRActionInterval.cpp
其实设定路径就是不断的刷新,将路径上的点赋给执行action的对象。
因此,既然我们要做一个椭圆的轨迹,我们就需要得到椭圆上每个点的坐标值,然后将其赋给执行action的对象。获得椭圆的轨迹,再次回想初中老师的教导——椭圆标准方程:x^2/a+y^2/b=1。
但这是个2次方程,李勇这个方程求x、y的值的时候会需要开方,而开方后还需要确定正负,虽然可以实现功能,但是给自己增加了不少代码量,也会浪费不少笔芯。所以我们要找一个更简单的公式——椭圆参数方程。
参数方程:x=acos(θ)y=bsin(θ);利用这个一次方程可以直观的计算出当前坐标点。
由椭圆的参数方程我们可以分别写出返回X/Y坐标值的函数:
[cpp]
view plaincopyprint?
static
inline
float tuoyuanXat(
float a,
float bx,
float c, ccTime t )//返回X坐标
{
//参数方程
return -a*cos(2*3.1415926*t)+a;
}
static
inline
float tuoyuanYat(
float a,
float by,
float c, ccTime t )//返回Y坐标
{
float b = sqrt(powf(a, 2) - powf(c, 2));//因为之前定义的参数是焦距c而不是短半轴b,所以需要计算出b
//参数方程
return b*sin(2*3.1415926*t);
}
然后实现根据中心左边、a、c确定椭圆:
[cpp]
view plaincopyprint?
//
//TuoyuanBy
//
LRTuoyuanBy* LRTuoyuanBy::actionWithDuration(ccTime t,
const lrTuoyuanConfig& c)//利用之前定义的椭圆的三个参数初始化椭圆
{
LRTuoyuanBy *pTuoyuanBy =
new LRTuoyuanBy();
pTuoyuanBy->initWithDuration(t, c);
pTuoyuanBy->autorelease();
return pTuoyuanBy;
}
bool
LRTuoyuanBy::initWithDuration(ccTime t, const lrTuoyuanConfig&
c)
{
if (CCActionInterval::initWithDuration(t))
{
m_sConfig = c;
return
true;
}
return
false;
}
void
LRTuoyuanBy::update(ccTime time)
{
if (m_pTarget)
{
CCPoint s_startPosition =m_sConfig.centerPosition;//中心点坐标
float a = m_sConfig.aLength;
float bx = m_sConfig.centerPosition.x;
float by = m_sConfig.centerPosition.y;
float c = m_sConfig.cLength;
float x = tuoyuanXat(a, bx, c, time);//调用之前的坐标计算函数来计算出坐标值
float y = tuoyuanYat(a, by, c, time);
m_pTarget->setPosition(ccpAdd(s_startPosition, ccp(x-a, y)));//由于我们画计算出的椭圆你做值是以原点为中心的,所以需要加上我们设定的中心点坐标
}
}
这样我们只需要在程序中像使用CCBezier一样使用LRTuoyuan,让精灵执行这个Action,他就会沿着我们设定的椭圆运动了。当然,只要你给出你自己的运动函数轨迹,精灵就会按照你自己设定的轨迹运动。
相关文章推荐
- cocos2d-x学习笔记(三)让精灵按照自己设定的运动轨迹行动(曲线移动)。(以椭圆轨迹为例)。
- (转)cocos2d-x学习笔记(三)让精灵按照自己设定的运动轨迹行动(曲线移动)。(以椭圆轨迹为例)
- cocos2d-x学习笔记(三)让精灵按照自己设定的运动轨迹行动(曲线移动)。(以椭圆轨迹为例)。
- 让精灵按照自己设定的运动轨迹行动(曲线移动)。(以椭圆轨迹为例)。
- 让精灵按照自己设定的运动轨迹行动(曲线移动)。(以椭圆轨迹为例)。
- cocos2d-x 让精灵按照自己设定的运动轨迹行动
- 让精灵按照自己设定的轨迹运动
- <转>cocos2d-x学习笔记(五)仿真树叶飘落效果的实现(精灵旋转、翻转、钟摆运动等综合运用)
- cocos2d-x学习笔记(五)仿真树叶飘落效果的实现(精灵旋转、翻转、钟摆运动等综合运用)
- Cocos2d-x学习笔记(五)仿真树叶飘落效果的实现(精灵旋转、翻转、钟摆运动等综合运用)
- Cocos2d-x学习笔记(三) —— 如何移动精灵
- (转)cocos2d-x学习笔记(五)仿真树叶飘落效果的实现(精灵旋转、翻转、钟摆运动等综合运用)
- cocos2d-x学习笔记(五)仿真树叶飘落效果的实现(精灵旋转、翻转、钟摆运动等综合运用)
- Cocos2d-x初学指南(3): 扩展CCAction制作自己的运动轨迹
- 【Cocos2d-X开发学习笔记】第06期:渲染框架之精灵类(CCSprite)的使用
- cocos2d-x学习笔记【二】导演、场景、层。精灵介绍
- 【Cocos2d-x3.0学习笔记 08】精灵来了
- 我的Cocos2d-x学习笔记(七)纹理缓存、帧缓存、精灵的创建、zOrder
- cocos2d-x 菜鸟学习笔记五(精灵与动画)
- cocos2d-x 3.1.1 学习笔记[2]Sprite 精灵