Cocos2d-x初学指南(3): 扩展CCAction制作自己的运动轨迹
cocos2d-x例子里面自带的基本运动动画很多种,但是仍然觉得还不够满意。幸好这个是开源的,我们可以参看他的源码,自己实现一个动作
首先就拿最熟悉的CCMoveTo吧。先看源码。
[cpp]
class CC_DLL CCMoveTo : public CCActionInterval
{
public:
/** initializes the action 小柒*/
[cpp]
bool initWithDuration(ccTime duration, const CCPoint& position);
virtual CCObject* copyWithZone(CCZone* pZone);
virtual void startWithTarget(CCNode *pTarget);
virtual void update(ccTime time);
public:
/** creates the action */
static CCMoveTo* actionWithDuration(ccTime duration, const CCPoint& position);
protected:
CCPoint m_endPosition;
CCPoint m_startPosition;
CCPoint m_delta;
};
是不是很简洁, 然后我们一起来看看各个函数的实现过程, 一般我们用的时候是
[cpp]
static CCMoveTo* actionWithDuration(ccTime duration, const CCPoint& position);
用这句话实例化的,我们来看看他的内部构造
[cpp]
CCMoveTo* CCMoveTo::actionWithDuration(ccTime duration, const CCPoint& position)
{
CCMoveTo *pMoveTo = new CCMoveTo();
pMoveTo->initWithDuration(duration, position);
pMoveTo->autorelease();
return pMoveTo;
}
很明显啦,他在里面先实例化了一下,然后进入初始化,接着我们也进去看看
[cpp]
bool CCMoveTo::initWithDuration(ccTime duration, const CCPoint& position)
{
if (CCActionInterval::initWithDuration(duration))
{
m_endPosition = position;
return true;
}
return false;
}
你看这里调用一下父类的初始化,只需要传个时间进去就行了,然后就是记录我们的各种参数啦。
然后主角来啦,最重要的是update()函数 这个就是我们动作改变的地方。一起来看看
void CCMoveTo::update(ccTime time)
{
if (m_pTarget)
{
m_pTarget->setPosition(ccp(m_startPosition.x + m_delta.x * time,
m_startPosition.y + m_delta.y * time)); //就是这句话了, m_delta是总的坐标宽度
}
}
void CCMoveTo::startWithTarget(CCNode *pTarget)
{
CCActionInterval::startWithTarget(pTarget);
m_startPosition = pTarget->getPosition();
m_delta = ccpSub(m_endPosition, m_startPosition); //从这里得到的m_delta然后在update里面
}
现在就做我们自己的路径吧
[cpp]
#include "CCActionInterval.h"
using namespace cocos2d;
class myAction : public CCActionInterval
{
public:
/** initializes the action */
bool initWithDuration(ccTime duration, const CCPoint& position);
virtual void startWithTarget(CCNode *pTarget);
virtual void update(ccTime time);
public:
/** creates the action */ www.zzzyk.com
static myAction* actionWithDuration(ccTime duration, const CCPoint& position);
protected:
CCPoint m_endPosition;
CCPoint m_startPosition;
};
[cpp]
#include "myAction.h"
#include "CCPointExtension.h"
void myAction::startWithTarget(CCNode *pTarget){
CCActionInterval::startWithTarget(pTarget);
m_startPosition = pTarget->getPosition();//这里得到刚开始的位置
}
myAction* myAction::actionWithDuration(ccTime duration, const CCPoint& position){
myAction * pmyAction=new myAction();
pmyAction->initWithDuration(duration, position);
pmyAction->autorelease();
return pmyAction;
}
//这个函数得到初始化数据
bool myAction::initWithDuration(ccTime duration, const CCPoint& position){
if (CCActionInterval::initWithDuration(duration))
{
m_endPosition = position; //这里得到圆心位置,就是要绕着哪里转
return true;
}
return false;
}
void myAction::update(ccTime time){
if (m_pTarget)
{
//这里的time就相当于当前时间占总的需要运行时间的百分比
/**这里轨迹就用一个圆
x=sin(t) y=(sin(t) ,当时间走完就是一圈,2*180=360度
*/
float tempx=(m_startPosition.x-m_endPosition.x)*(m_startPosition.x-m_endPosition.x);
float tempy=(m_startPosition.y-m_endPosition.y)*(m_startPosition.y-m_endPosition.y);
float r=sqrt(tempx+tempy);
float x=r*sin(2*3.14*time);
float y=r*cos(2*3.14*time);
m_pTarget->setPosition(ccpAdd(m_startPosition,ccp(x,y)));
}
}
使用方法:
在需要用的类里面加#include "myAction.h"
CCFiniteTimeAction *action5= myAction::actionWithDuration(15,ccp(x+250,y+150));
这样调用就可以了
birdSpite->runAction(action5);
补充:移动开发 , 其他 ,