最近在翻帖子的时候发现很多大牛都自己实现自定义动作,而不是通过各种动作进行组合,正好最近需要一个圆周运动的效果,就自己写了一个自定义的动作,这里备注下大致的实现思路。
CONTENTS
备注:
该动作并未实际应用在游戏中,可能有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" //http://202.113.29.3/nankaisource/mathhands/Elementary%20mathematics/0103/010301/01030101.htm 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);
截图如下:
发表评论