当前位置:编程学习 > wap >>

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);

 

补充:移动开发 , 其他 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,