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__ |
class CircleMoveAct : public cocos2d::CCActionInterval |
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 ); |
static CircleMoveAct* create( float duration, const cocos2d::CCPoint& center, float scale, float angle); |
cocos2d::CCPoint m_center; |
cocos2d::CCPoint m_initPos; |
#endif // __CIRCLE_MOVE_ACT_H__ |
CircleMoveAct.cpp:
#include "CircleMoveAct.h" |
CircleMoveAct* CircleMoveAct::create( float duration, const CCPoint& center, float scale, float angle) |
CircleMoveAct *pRet = new CircleMoveAct(); |
pRet->initWithDuration(duration, center, scale, angle); |
bool CircleMoveAct::initWithDuration( float duration, const CCPoint& center, float scaleDiff, float angle) |
if (CCActionInterval::initWithDuration(duration)) |
this ->m_duration = duration; |
this ->m_scaleDiff = scaleDiff; |
this ->m_currScale = 1.0f; |
this ->m_anglePreFrame = angle / duration * CCDirector::sharedDirector()->getAnimationInterval() / (180 / M_PI); |
CCObject* CircleMoveAct::copyWithZone(CCZone *pZone) |
CircleMoveAct* pCopy = NULL; |
if (pZone && pZone->m_pCopyObject) |
pCopy = (CircleMoveAct*)(pZone->m_pCopyObject); |
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); |
void CircleMoveAct::startWithTarget(CCNode *pTarget) |
CCActionInterval::startWithTarget(pTarget); |
m_initPos = pTarget->getPosition(); |
void CircleMoveAct::update( float time ) |
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); |
CCDrawNode *node = CCDrawNode::create(); |
node->drawDot(newPos,3,ccc4f(128,128,128,128)); |
m_pTarget->getParent()->addChild(node); |
正常调用方式:
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)); |
CircleMoveAct *act = CircleMoveAct::create(10,ccp(size.width/2, size.height/2), 0.0f,1500); |
截图如下:
缩放调用方式:
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)); |
CircleMoveAct *act = CircleMoveAct::create(10,ccp(size.width/2, size.height/2), 0.01f,1500); |
截图如下: