文章转载自:http://blog.sina.com.cn/s/blog_6084f588010195iv.html
感谢分享。转载仅供学习备份,不作他用。
CCFreeFallBy 定义了一个自由落体运动。
自由落体是一个有限时间运动,所以需要继承CCActionInterval,
如果是瞬时运动则需要继承CCActionInstant,
需要注意的是CCActionInterval需要指定时间,这里我计算了时间,不过有偏差,当使用队列时效果不太好,
这里当运用条件结束时采取了结束运动的方式来解决
另外需要知道公式就可以了 s=1.0/2.0*g*t*t;
g的大小根据自己去指定就可以了
class CCFreeFallBy:public cocos2d::CCActionInterval {
private:
int yOffsetElasped;
float timeElasped;
public:
bool initWithOffset(const CCPoint& deltaPosition);
virtual CCObject* copyWithZone(CCZone* pZone);
virtual void startWithTarget(CCNode *pTarget);
virtual CCActionInterval* reverse(void);
virtual void update(float time);
virtual bool isDone(void);
public:
static CCFreeFallBy * create(const CCPoint& deltaPosition);
protected:
CCPoint m_positionDelta;
CCPoint m_startPosition;
CCPoint m_targetPosition;
CCPoint m_previousPosition;
};
#include "CCFreeFall.h"
const float kFreeFallSpeed=30;
//
// MoveBy
//
CCFreeFallBy* CCFreeFallBy::create(const CCPoint& deltaPosition)
{
CCFreeFallBy *pRet = new CCFreeFallBy();
pRet->initWithOffset(deltaPosition);
pRet->autorelease();
return pRet;
}
bool CCFreeFallBy::initWithOffset(const CCPoint& deltaPosition)
{
float dropTime=sqrt(2.0*abs(deltaPosition.y)/kFreeFallSpeed)*0.1 ;
if (CCActionInterval::initWithDuration(dropTime));
{
yOffsetElasped=0;
m_positionDelta = deltaPosition;
return true;
}
return false;
}
bool CCFreeFallBy::isDone(void){
if (m_targetPosition.y>=this->m_pTarget->getPosition().y) {
return true;
}
return false;
}
CCObject* CCFreeFallBy::copyWithZone(CCZone *pZone)
{
CCZone* pNewZone = NULL;
CCFreeFallBy* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCFreeFallBy*)(pZone->m_pCopyObject);
}
else
{
pCopy = new CCFreeFallBy();
pZone = pNewZone = new CCZone(pCopy);
}
CCActionInterval::copyWithZone(pZone);
pCopy->initWithOffset(m_positionDelta);
CC_SAFE_DELETE(pNewZone);
return pCopy;
}
void CCFreeFallBy::startWithTarget(CCNode *pTarget)
{
CCActionInterval::startWithTarget(pTarget);
m_previousPosition = m_startPosition = pTarget->getPosition();
m_targetPosition=ccpAdd(m_startPosition, m_positionDelta);
}
CCActionInterval* CCFreeFallBy::reverse(void)
{
return CCFreeFallBy::create(ccp( -m_positionDelta.x, -m_positionDelta.y));
}
void CCFreeFallBy::update(float t)
{
timeElasped+=t;
if (m_pTarget)
{
float yMoveOffset=1.0/2.0*kFreeFallSpeed*timeElasped*timeElasped;
#if CC_ENABLE_STACKABLE_ACTIONS
CCPoint newPos = ccp(m_startPosition.x, m_startPosition.y-yMoveOffset);
if (m_targetPosition.y>newPos.y) {
newPos.y=m_targetPosition.y;
m_pTarget->stopAction(this);
}
m_pTarget->setPosition(newPos);
#else
m_pTarget->setPosition(ccpAdd( m_startPosition, ccpMult(m_positionDelta, t)));
#endif // CC_ENABLE_STACKABLE_ACTIONS
}
}