cocos2dx学习笔记:自定义动作实现圆周运动

From: http://cstriker1407.info/blog/cocos2dx-study-notes-custom-actions-realization-of-circular-motion/

最近在翻帖子的时候发现很多大牛都自己实现自定义动作,而不是通过各种动作进行组合,正好最近需要一个圆周运动的效果,就自己写了一个自定义的动作,这里备注下大致的实现思路。

备注:

该动作并未实际应用在游戏中,可能有bug。

数学复习:

截图来自【 http://202.113.29.3/nankaisource/mathhands/Elementary%20mathematics/0103/010301/01030101.htm 】

实现方式:

可参考这篇文章来实现:【 http://blog.csdn.net/u012945598/article/details/17605409 】 

作者自己也写了一个功能增强版的圆周运动,可以实现螺旋线式的圆周运动。代码比较简单,就不在细说了。

自己的实现:

CircleMoveAct.h:

#ifndef __CIRCLE_MOVE_ACT_H__
#define __CIRCLE_MOVE_ACT_H__
 
#include "cocos2d.h"
 
class CircleMoveAct : public cocos2d::CCActionInterval
{
public:
    bool initWithDuration(float duration, const cocos2d::CCPoint& center, float scaleDiff, float angle);
     
    virtual cocos2d::CCObject* copyWithZone(cocos2d::CCZone* pZone);
    virtual void startWithTarget(cocos2d::CCNode *pTarget);
    virtual void update(float time);
public:
    static CircleMoveAct* create(float duration, const cocos2d::CCPoint& center, float scale, float angle);
 
protected:
 
    float m_duration;
    cocos2d::CCPoint m_center;
    float m_scaleDiff;
    float m_currScale;
    float m_angle; 
    float m_anglePreFrame;
    int m_frameCnts;
    cocos2d::CCPoint m_initPos;
};
 
#endif // __CIRCLE_MOVE_ACT_H__

CircleMoveAct.cpp:

#include "CircleMoveAct.h"
USING_NS_CC;
 
 
CircleMoveAct* CircleMoveAct::create(float duration, const CCPoint& center, float scale, float angle)
{
    CircleMoveAct *pRet = new CircleMoveAct();
    pRet->initWithDuration(duration, center, scale, angle);
    pRet->autorelease();
 
    return pRet;
}
 
bool CircleMoveAct::initWithDuration(float duration, const CCPoint& center, float scaleDiff, float angle)
{
    if (CCActionInterval::initWithDuration(duration))
    {
        this->m_duration = duration;
        this->m_center = center;
        this->m_scaleDiff = scaleDiff;
        this->m_currScale = 1.0f;
        this->m_angle = angle;
 
        /************************************************************************/
        /* 计算每次update调用时需要转动的弧度                                   */
        /************************************************************************/
        this->m_anglePreFrame = angle / duration * CCDirector::sharedDirector()->getAnimationInterval() / (180 / M_PI);
        this->m_frameCnts = 0;
        return true;
    }
    return false;
}
 
CCObject* CircleMoveAct::copyWithZone(CCZone *pZone)
{
    CCZone* pNewZone = NULL;
    CircleMoveAct* pCopy = NULL;
    if(pZone && pZone->m_pCopyObject)
    {
        pCopy = (CircleMoveAct*)(pZone->m_pCopyObject);
    }
    else
    {
        pCopy = new CircleMoveAct();
        pZone = pNewZone = new CCZone(pCopy);
    }
 
    CCActionInterval::copyWithZone(pZone);
    pCopy->initWithDuration(m_duration, m_center, m_scaleDiff, m_angle);
 
    CC_SAFE_DELETE(pNewZone);
    return pCopy;
}
 
void CircleMoveAct::startWithTarget(CCNode *pTarget)
{
    CCActionInterval::startWithTarget(pTarget);
    m_initPos = pTarget->getPosition();
}
void CircleMoveAct::update(float time)
{
    m_frameCnts++;
    m_currScale += m_scaleDiff;
 
    CCPoint newPos = ccpRotateByAngle(m_initPos, m_center, m_frameCnts * m_anglePreFrame);
    CCPoint diff = ccpSub(newPos, m_center);
    newPos = diff * m_currScale + m_center;
     
    m_pTarget->setPosition(newPos);
 
 
//debug
#if 0
    CCDrawNode *node = CCDrawNode::create();
    node->drawDot(newPos,3,ccc4f(128,128,128,128));
    m_pTarget->getParent()->addChild(node);
#endif
 
}

正常调用方式:

CCSize size = CCDirector::sharedDirector()->getVisibleSize();
CCSprite *test = CCSprite::create("CloseNormal.png");
test->setPosition(ccp(size.width/2 + 20, size.height/2));//设置起点
test->setAnchorPoint(ccp(0.5,0.5));
//设置用时,圆心,是否缩放(不缩放设置为0.0f),旋转角度
CircleMoveAct *act = CircleMoveAct::create(10,ccp(size.width/2, size.height/2), 0.0f,1500);
test->runAction(act);
this->addChild(test);

 截图如下:

缩放调用方式:

CCSize size = CCDirector::sharedDirector()->getVisibleSize();
CCSprite *test = CCSprite::create("CloseNormal.png");
test->setPosition(ccp(size.width/2 + 20, size.height/2));//设置起点
test->setAnchorPoint(ccp(0.5,0.5));
//设置用时,圆心,缩放递增值0.01f,旋转角度
CircleMoveAct *act = CircleMoveAct::create(10,ccp(size.width/2, size.height/2), 0.01f,1500);
test->runAction(act);
this->addChild(test);

截图如下:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值