cocos2dx 自带了一些属性变化的函数。均继承于CCActionInterval ,有了CCActionInterval,继承后便可以通过重写,在update方法中可以做各种属性变化。而轨迹运动则是其中一大项。
写过矩形的轨迹,圆形的轨迹,因为比较熟悉,都比较容易做出来。直到碰到椭圆。
这次要做角色选择界面,主要一个设计点在于几种门派的轮回转运,并且要有立体效果,椭圆轨迹是必需的了。
着手,开始。搜索到了些资源,再自己优化一下,因为我不仅仅需要的是可以整个椭圆的轨迹,还要运动其中某一段,这一段长短不好描述,就用角度吧。
头文件:
class TuoyuanBy : public CCActionInterval
{
public:
bool initWithDuration(float t, CCPoint center , float al , float bl, float startAngle,float detlaAngle, bool isClockWise);
virtual void startWithTarget(CCNode *pTarget);
virtual void update(float time);//利用update函数来不断的设定坐标
public:
//用“动作持续时间”和“椭圆控制参数”创建动作 , t-持续时间 center-椭圆中心点 al-长边长 bl-短边长 starAngle-起始角度 detlaAngle-变化角度 // isClockWise-是否顺时针方向 static TuoyuanBy *create(float t, CCPoint center , float al , float bl ,float startAngle, float detlaAngle , bool isClockWise);//以下inline函数是重点,关于这两个方法,我也搞不懂,在椭圆图形上看三角函数,并不合理,但使用后确实是可以实现椭圆形的轨迹,可以只是一个大概轨迹吧,不是 //很精确的 , 自己通过解二元函数又解不出来,太烦了,有更精确的计算跪求分享
protected:
inline float tuoyuanXat(float angle )//返回X坐标
{
//参数方程
return m_a*cos(angle);
}
inline float tuoyuanYat(float angle )//返回Y坐标
{
return m_b*sin(angle);
}
protected:
CCPoint m_center;
float m_a;
float m_b;
float m_detlaAngle;
bool m_isClockWise;
CCPoint m_startPosition;
float m_startAngle;
};
实现文件:
TuoyuanBy* TuoyuanBy::create(float t, CCPoint center , float al , float bl , float startAngle,float detlaAngle, bool isClockWise)
{
TuoyuanBy* mwcb = new TuoyuanBy();
mwcb->initWithDuration(t ,center ,al, bl, startAngle,detlaAngle,isClockWise);
mwcb->autorelease();
return mwcb;
}
bool TuoyuanBy::initWithDuration(float t, CCPoint center , float al , float bl, float startAngle,float detlaAngle, bool isClockWise){
if (CCActionInterval::initWithDuration(t)) {
m_center = center;
m_a = al;
m_b = bl;
m_isClockWise = isClockWise;
m_detlaAngle = 2* 3.1415926 * detlaAngle/360; //为了方便直观,传进来的angle是一个角度值,不是弧度值
m_startAngle = 2* 3.1415926 * startAngle/360;
return true;
}
return false;
}
void TuoyuanBy::startWithTarget(CCNode *pTarget)
{
CCActionInterval::startWithTarget(pTarget);
//设置初始位置,位于m_startAngle处
float xx = tuoyuanXat(m_startAngle);
float yy = tuoyuanYat(m_startAngle);
pTarget->setPosition(CCPoint(xx + m_center.x, yy + m_center.y));
m_startPosition = pTarget->getPosition();
}
void TuoyuanBy::update(float time){
if (m_pTarget)
{
float angle = m_startAngle + m_detlaAngle * time;
float xx = tuoyuanXat(angle);
float yy = tuoyuanYat(angle);
m_pTarget->setPosition(CCPoint(xx + m_center.x, yy + m_center.y));
}
}
再写个TuoyuanTo继承TuoyuanBy ,个人一般用 TuoyuanTo。TuoyuanTo会有个问题,比如如果是顺时针运动,而角度是从0到270度,这个情况下求m_detlaAngle是会出问题的,要做些判断求值。