axmol/cocos2dx/actions/CCIntervalAction.cpp

1941 lines
42 KiB
C++
Raw Normal View History

/****************************************************************************
Copyright (c) 2010 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "CCIntervalAction.h"
#include "CCSprite.h"
#include "CCNode.h"
2010-08-25 10:19:20 +08:00
#include "CGPointExtension.h"
2010-09-02 16:46:25 +08:00
#include "platform/CCXMath.h"
2010-08-25 14:14:31 +08:00
#include <stdarg.h>
2010-08-06 14:44:17 +08:00
namespace cocos2d {
//
// IntervalAction
//
CCIntervalAction* CCIntervalAction::actionWithDuration(ccTime d)
{
2010-08-06 14:44:17 +08:00
CCIntervalAction *pAction = new CCIntervalAction();
pAction->initWithDuration(d);
pAction->autorelease();
return pAction;
}
2010-08-11 14:03:46 +08:00
bool CCIntervalAction::initWithDuration(cocos2d::ccTime d)
{
2010-08-06 14:44:17 +08:00
m_fDuration = d;
// prevent division by 0
// This comparison could be in step:, but it might decrease the performance
// by 3% in heavy based action games.
if (m_fDuration == 0)
{
m_fDuration = FLT_EPSILON;
}
m_elapsed = 0;
m_bFirstTick = true;
2010-08-11 14:03:46 +08:00
return true;
}
NSObject* CCIntervalAction::copyWithZone(NSZone *pZone)
{
2010-08-06 14:44:17 +08:00
NSZone* pNewZone = NULL;
CCIntervalAction* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCIntervalAction*)(pZone->m_pCopyObject);
2010-08-06 14:44:17 +08:00
}
else
{
// action's base class , must be called using __super::copyWithZone(), after overriding from derived class
assert(0);
pCopy = new CCIntervalAction();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCFiniteTimeAction::copyWithZone(pZone);
2010-08-06 14:44:17 +08:00
CCX_SAFE_DELETE(pNewZone);
pCopy->initWithDuration(m_fDuration);
return pCopy;
}
bool CCIntervalAction::isDone(void)
{
2010-08-09 11:46:35 +08:00
return m_elapsed >= m_fDuration;
}
void CCIntervalAction::step(ccTime dt)
{
2010-08-06 14:44:17 +08:00
if (m_bFirstTick)
{
m_bFirstTick = false;
m_elapsed = 0;
}
else
{
m_elapsed += dt;
}
2010-08-10 17:20:28 +08:00
// update(min(1, m_elapsed/m_fDuration));
update(1 > m_elapsed/m_fDuration ? m_elapsed/m_fDuration : 1);
}
2010-08-17 11:43:10 +08:00
void CCIntervalAction::setAmplitudeRate(CGFloat amp)
{
// Abstract class needs implementation
assert(0);
}
CGFloat CCIntervalAction::getAmplitudeRate(void)
{
// Abstract class needs implementation
assert(0);
return 0;
}
void CCIntervalAction::startWithTarget(CCNode *pTarget)
{
2010-09-02 14:54:42 +08:00
CCFiniteTimeAction::startWithTarget(pTarget);
2010-08-06 14:44:17 +08:00
m_elapsed = 0.0f;
m_bFirstTick = true;
}
CCIntervalAction* CCIntervalAction::reverse(void)
{
2010-08-06 14:44:17 +08:00
/*
NSException* myException = [NSException
exceptionWithName:@"ReverseActionNotImplemented"
reason:@"Reverse Action not implemented"
userInfo:nil];
@throw myException;
*/
return NULL;
}
//
// Sequence
//
CCSequence* CCSequence::actionOneTwo(cocos2d::CCFiniteTimeAction *pActionOne, cocos2d::CCFiniteTimeAction *pActionTwo)
{
2010-08-06 14:44:17 +08:00
CCSequence *pSequence = new CCSequence();
pSequence->initOneTwo(pActionOne, pActionTwo);
pSequence->autorelease();
return pSequence;
}
2010-08-06 14:44:17 +08:00
CCFiniteTimeAction* CCSequence::actions(cocos2d::CCFiniteTimeAction *pAction1, ...)
{
2010-08-06 14:44:17 +08:00
va_list params;
va_start(params, pAction1);
CCFiniteTimeAction *pNow;
CCFiniteTimeAction *pPrev = pAction1;
while (pAction1)
{
pNow = va_arg(params, CCFiniteTimeAction*);
if (pNow)
{
pPrev = actionOneTwo(pPrev, pNow);
}
else
{
break;
}
}
va_end(params);
return pPrev;
}
2010-08-11 14:03:46 +08:00
bool CCSequence::initOneTwo(cocos2d::CCFiniteTimeAction *pActionOne, cocos2d::CCFiniteTimeAction *pActionTwo)
{
2010-08-06 14:44:17 +08:00
assert(pActionOne != NULL);
assert(pActionTwo != NULL);
ccTime d = pActionOne->getDuration() + pActionTwo->getDuration();
2010-09-02 14:54:42 +08:00
CCIntervalAction::initWithDuration(d);
2010-08-06 14:44:17 +08:00
m_pActions[0] = pActionOne;
pActionOne->retain();
m_pActions[1] = pActionTwo;
pActionTwo->retain();
2010-08-11 14:03:46 +08:00
return true;
}
NSObject* CCSequence::copyWithZone(NSZone *pZone)
{
2010-08-06 14:44:17 +08:00
NSZone* pNewZone = NULL;
CCSequence* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCSequence*)(pZone->m_pCopyObject);
2010-08-06 14:44:17 +08:00
}
else
{
pCopy = new CCSequence();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::copyWithZone(pZone);
2010-08-06 14:44:17 +08:00
pCopy->initOneTwo((CCFiniteTimeAction*)(m_pActions[0]->copy()->autorelease()),
(CCFiniteTimeAction*)(m_pActions[1]->copy()->autorelease()));
2010-08-06 14:44:17 +08:00
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
CCSequence::~CCSequence(void)
{
2010-08-06 14:44:17 +08:00
m_pActions[0]->release();
m_pActions[1]->release();
}
void CCSequence::startWithTarget(CCNode *pTarget)
{
2010-09-02 14:54:42 +08:00
CCIntervalAction::startWithTarget(pTarget);
2010-08-06 14:44:17 +08:00
m_split = m_pActions[0]->getDuration() / m_fDuration;
m_last = -1;
}
void CCSequence::stop(void)
{
2010-08-06 14:44:17 +08:00
m_pActions[0]->stop();
m_pActions[1]->stop();
2010-09-02 14:54:42 +08:00
CCIntervalAction::stop();
}
void CCSequence::update(cocos2d::ccTime time)
{
2010-08-06 14:44:17 +08:00
int found = 0;
ccTime new_t = 0.0f;
if (time >= m_split)
{
found = 1;
if (m_split == 1)
{
new_t = 1;
}
else
{
new_t = (time - m_split) / (1 - m_split);
}
}
else
{
found = 0;
if (m_split != 0)
{
new_t = time / m_split;
}
else
{
new_t = 1;
}
}
if (m_last == -1 && found == 1)
{
m_pActions[0]->startWithTarget(m_pTarget);
m_pActions[0]->update(1.0f);
m_pActions[0]->stop();
}
if (m_last != found)
{
if (m_last != -1)
{
2010-08-06 15:48:53 +08:00
m_pActions[m_last]->update(1.0f);
m_pActions[m_last]->stop();
2010-08-06 14:44:17 +08:00
}
m_pActions[found]->startWithTarget(m_pTarget);
}
m_pActions[found]->update(new_t);
m_last = found;
}
CCIntervalAction* CCSequence::reverse(void)
{
2010-08-06 14:44:17 +08:00
return CCSequence::actionOneTwo(m_pActions[1]->reverse(), m_pActions[0]->reverse());
}
//
// Repeat
//
CCRepeat* CCRepeat::actionWithAction(cocos2d::CCFiniteTimeAction *pAction, unsigned int times)
{
2010-08-06 14:44:17 +08:00
CCRepeat* pRepeat = new CCRepeat();
pRepeat->initWithAction(pAction, times);
pRepeat->autorelease();
return pRepeat;
}
2010-08-11 14:03:46 +08:00
bool CCRepeat::initWithAction(cocos2d::CCFiniteTimeAction *pAction, unsigned int times)
{
2010-08-06 14:44:17 +08:00
ccTime d = pAction->getDuration() * times;
2010-09-02 14:54:42 +08:00
if (CCIntervalAction::initWithDuration(d))
2010-08-06 14:44:17 +08:00
{
m_uTimes = times;
m_pOther = pAction;
pAction->retain();
m_uTotal = 0;
2010-08-11 14:03:46 +08:00
return true;
2010-08-06 14:44:17 +08:00
}
2010-08-11 14:03:46 +08:00
return false;
}
NSObject* CCRepeat::copyWithZone(cocos2d::NSZone *pZone)
{
2010-08-06 14:44:17 +08:00
NSZone* pNewZone = NULL;
CCRepeat* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCRepeat*)(pZone->m_pCopyObject);
2010-08-06 14:44:17 +08:00
}
else
{
pCopy = new CCRepeat();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::copyWithZone(pZone);
2010-08-06 14:44:17 +08:00
pCopy->initWithAction((CCFiniteTimeAction*)(m_pOther->copy()->autorelease()), m_uTimes);
2010-08-06 14:44:17 +08:00
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
CCRepeat::~CCRepeat(void)
{
2010-08-06 14:44:17 +08:00
m_pOther->release();
}
void CCRepeat::startWithTarget(CCNode *pTarget)
{
2010-08-06 14:44:17 +08:00
m_uTotal = 0;
2010-09-02 14:54:42 +08:00
CCIntervalAction::startWithTarget(pTarget);
2010-08-06 14:44:17 +08:00
m_pOther->startWithTarget(pTarget);
}
void CCRepeat::stop(void)
{
2010-08-06 14:44:17 +08:00
m_pOther->stop();
2010-09-02 14:54:42 +08:00
CCIntervalAction::stop();
}
// issue #80. Instead of hooking step:, hook update: since it can be called by any
// container action like Repeat, Sequence, AccelDeccel, etc..
void CCRepeat::update(cocos2d::ccTime time)
{
2010-08-06 14:44:17 +08:00
ccTime t = time * m_uTimes;
if (t > m_uTotal + 1)
{
m_pOther->update(1.0f);
m_uTotal++;
m_pOther->stop();
m_pOther->startWithTarget(m_pTarget);
// repeat is over?
if (m_uTotal == m_uTimes)
{
// so, set it in the original position
m_pOther->update(0);
}
else
{
// no ? start next repeat with the right update
// to prevent jerk (issue #390)
m_pOther->update(t - m_uTotal);
}
}
else
{
float r = fmodf(t, 1.0f);
// fix last repeat position
// else it could be 0.
if (time == 1.0f)
{
r = 1.0f;
m_uTotal++; // this is the added line
}
2010-08-10 17:20:28 +08:00
// m_pOther->update(min(r, 1));
m_pOther->update(r > 1 ? 1 : r);
2010-08-06 14:44:17 +08:00
}
}
bool CCRepeat::isDone(void)
{
2010-08-06 14:44:17 +08:00
return m_uTotal == m_uTimes;
}
CCIntervalAction* CCRepeat::reverse(void)
{
2010-08-06 14:44:17 +08:00
return CCRepeat::actionWithAction(m_pOther->reverse(), m_uTimes);
}
//
// RepeatForever
//
CCRepeatForever::~CCRepeatForever()
{
m_pOther->release();
}
CCRepeatForever *CCRepeatForever::actionWithAction(CCIntervalAction *pAction)
{
CCRepeatForever *pRet = new CCRepeatForever();
if (pRet && pRet->initWithAction(pAction))
{
pRet->autorelease();
return pRet;
}
CCX_SAFE_DELETE(pRet);
return NULL;
}
CCRepeatForever *CCRepeatForever::initWithAction(CCIntervalAction *pAction)
{
pAction->retain();
m_pOther = pAction;
return this;
}
NSObject* CCRepeatForever::copyWithZone(NSZone *pZone)
{
NSZone* pNewZone = NULL;
CCRepeatForever* pRet = NULL;
if(pZone && pZone->m_pCopyObject) //in case of being called at sub class
{
pRet = (CCRepeatForever*)(pZone->m_pCopyObject);
}
else
{
pRet = new CCRepeatForever();
pZone = pNewZone = new NSZone(pRet);
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::copyWithZone(pZone);
// win32 : use the m_pOther's copy object.
pRet->initWithAction((CCIntervalAction*)(m_pOther->copy()->autorelease()));
CCX_SAFE_DELETE(pNewZone);
return pRet;
}
void CCRepeatForever::startWithTarget(CCNode* pTarget)
{
2010-09-02 14:54:42 +08:00
CCIntervalAction::startWithTarget(pTarget);
m_pOther->startWithTarget(pTarget);
}
void CCRepeatForever::step(ccTime dt)
{
m_pOther->step(dt);
if (m_pOther->isDone())
{
ccTime diff = dt + m_pOther->getDuration() - m_pOther->getElapsed();
m_pOther->startWithTarget(m_pTarget);
// to prevent jerk. issue #390
m_pOther->step(diff);
}
}
bool CCRepeatForever::isDone()
{
return false;
}
CCIntervalAction *CCRepeatForever::reverse()
{
return (CCIntervalAction*)(CCRepeatForever::actionWithAction(m_pOther->reverse()));
}
//
// Spawn
//
2010-08-06 14:44:17 +08:00
CCFiniteTimeAction* CCSpawn::actions(cocos2d::CCFiniteTimeAction *pAction1, ...)
{
2010-08-06 14:44:17 +08:00
va_list params;
va_start(params, pAction1);
CCFiniteTimeAction *pNow;
CCFiniteTimeAction *pPrev = pAction1;
while (pAction1)
{
pNow = va_arg(params, CCFiniteTimeAction*);
if (pNow)
{
pPrev = actionOneTwo(pPrev, pNow);
}
else
{
break;
}
}
va_end(params);
return pPrev;
}
2010-08-06 14:44:17 +08:00
CCSpawn* CCSpawn::actionOneTwo(cocos2d::CCFiniteTimeAction *pAction1, cocos2d::CCFiniteTimeAction *pAction2)
{
2010-08-06 14:44:17 +08:00
CCSpawn *pSpawn = new CCSpawn();
pSpawn->initOneTwo(pAction1, pAction2);
pSpawn->autorelease();
return pSpawn;
}
2010-08-11 14:03:46 +08:00
bool CCSpawn:: initOneTwo(CCFiniteTimeAction *pAction1, CCFiniteTimeAction *pAction2)
2010-08-06 14:44:17 +08:00
{
assert(pAction1 != NULL);
assert(pAction2 != NULL);
ccTime d1 = pAction1->getDuration();
ccTime d2 = pAction2->getDuration();
// __super::initWithDuration(fmaxf(d1, d2));
2010-09-02 16:46:25 +08:00
float maxd = (d1 >= d2 || CCXMath::isnanCocos2d(d2)) ? d1 : d2;
2010-09-02 14:54:42 +08:00
CCIntervalAction::initWithDuration(maxd);
2010-08-06 14:44:17 +08:00
m_pOne = pAction1;
m_pTwo = pAction2;
if (d1 > d2)
{
2010-08-21 11:03:18 +08:00
m_pTwo = CCSequence::actionOneTwo(pAction2, CCDelayTime::actionWithDuration(d1 - d2));
2010-08-06 14:44:17 +08:00
} else
if (d1 < d2)
{
m_pOne = CCSequence::actionOneTwo(pAction1, CCDelayTime::actionWithDuration(d2 - d1));
}
pAction1->retain();
pAction2->retain();
2010-08-11 14:03:46 +08:00
return true;
}
NSObject* CCSpawn::copyWithZone(cocos2d::NSZone *pZone)
{
2010-08-06 14:44:17 +08:00
NSZone* pNewZone = NULL;
CCSpawn* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCSpawn*)(pZone->m_pCopyObject);
2010-08-06 14:44:17 +08:00
}
else
{
pCopy = new CCSpawn();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::copyWithZone(pZone);
2010-08-06 14:44:17 +08:00
pCopy->initOneTwo((CCFiniteTimeAction*)(m_pOne->copy()->autorelease()),
(CCFiniteTimeAction*)(m_pTwo->copy()->autorelease()));
2010-08-06 14:44:17 +08:00
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
CCSpawn::~CCSpawn(void)
{
2010-08-06 14:44:17 +08:00
m_pOne->release();
m_pTwo->release();
}
void CCSpawn::startWithTarget(CCNode *pTarget)
{
2010-09-02 14:54:42 +08:00
CCIntervalAction::startWithTarget(pTarget);
2010-08-06 14:44:17 +08:00
m_pOne->startWithTarget(pTarget);
m_pTwo->startWithTarget(pTarget);
}
void CCSpawn::stop(void)
{
2010-08-06 14:44:17 +08:00
m_pOne->stop();
m_pTwo->stop();
2010-09-02 14:54:42 +08:00
CCIntervalAction::stop();
}
void CCSpawn::update(cocos2d::ccTime time)
{
2010-08-06 14:44:17 +08:00
m_pOne->update(time);
m_pTwo->update(time);
}
CCIntervalAction* CCSpawn::reverse(void)
{
2010-08-06 14:44:17 +08:00
return CCSpawn::actionOneTwo(m_pOne->reverse(), m_pTwo->reverse());
}
//
// RotateTo
//
CCRotateTo* CCRotateTo::actionWithDuration(cocos2d::ccTime duration, float fDeltaAngle)
{
2010-08-06 14:44:17 +08:00
CCRotateTo* pRotateTo = new CCRotateTo();
pRotateTo->initWithDuration(duration, fDeltaAngle);
pRotateTo->autorelease();
return pRotateTo;
}
2010-08-11 14:03:46 +08:00
bool CCRotateTo::initWithDuration(cocos2d::ccTime duration, float fDeltaAngle)
{
2010-09-02 14:54:42 +08:00
if (CCIntervalAction::initWithDuration(duration))
2010-08-06 14:44:17 +08:00
{
m_fDstAngle = fDeltaAngle;
2010-08-11 14:03:46 +08:00
return true;
2010-08-06 14:44:17 +08:00
}
2010-08-11 14:03:46 +08:00
return false;
}
NSObject* CCRotateTo::copyWithZone(cocos2d::NSZone *pZone)
{
2010-08-06 14:44:17 +08:00
NSZone* pNewZone = NULL;
CCRotateTo* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCRotateTo*)(pZone->m_pCopyObject);
2010-08-06 14:44:17 +08:00
}
else
{
pCopy = new CCRotateTo();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::copyWithZone(pZone);
2010-08-06 14:44:17 +08:00
pCopy->initWithDuration(m_fDuration, m_fDstAngle);
//Action *copy = [[[self class] allocWithZone: zone] initWithDuration:[self duration] angle: angle];
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
void CCRotateTo::startWithTarget(CCNode *pTarget)
{
2010-09-02 14:54:42 +08:00
CCIntervalAction::startWithTarget(pTarget);
2010-08-06 14:44:17 +08:00
m_fStartAngle = pTarget->getRotation();
2010-08-06 14:44:17 +08:00
if (m_fStartAngle > 0)
{
m_fStartAngle = fmodf(m_fStartAngle, 360.0f);
}
else
{
m_fStartAngle = fmodf(m_fStartAngle, -360.0f);
}
m_fDiffAngle = m_fDstAngle - m_fStartAngle;
if (m_fDiffAngle > 180)
{
m_fDiffAngle -= 360;
}
if (m_fDiffAngle < -180)
{
m_fDiffAngle += 360;
}
}
void CCRotateTo::update(cocos2d::ccTime time)
{
m_pTarget->setRotation(m_fStartAngle + m_fDiffAngle * time);
}
//
// RotateBy
//
CCRotateBy* CCRotateBy::actionWithDuration(cocos2d::ccTime duration, float fDeltaAngle)
{
2010-08-06 15:48:53 +08:00
CCRotateBy *pRotateBy = new CCRotateBy();
pRotateBy->initWithDuration(duration, fDeltaAngle);
pRotateBy->autorelease();
return pRotateBy;
}
2010-08-11 14:03:46 +08:00
bool CCRotateBy::initWithDuration(cocos2d::ccTime duration, float fDeltaAngle)
{
2010-09-02 14:54:42 +08:00
if (CCIntervalAction::initWithDuration(duration))
2010-08-06 15:48:53 +08:00
{
m_fAngle = fDeltaAngle;
2010-08-11 14:03:46 +08:00
return true;
2010-08-06 15:48:53 +08:00
}
2010-08-11 14:03:46 +08:00
return false;
}
NSObject* CCRotateBy::copyWithZone(cocos2d::NSZone *pZone)
{
2010-08-06 15:48:53 +08:00
NSZone* pNewZone = NULL;
CCRotateBy* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCRotateBy*)(pZone->m_pCopyObject);
2010-08-06 15:48:53 +08:00
}
else
{
pCopy = new CCRotateBy();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::copyWithZone(pZone);
2010-08-06 15:48:53 +08:00
pCopy->initWithDuration(m_fDuration, m_fAngle);
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
void CCRotateBy::startWithTarget(CCNode *pTarget)
{
2010-09-02 14:54:42 +08:00
CCIntervalAction::startWithTarget(pTarget);
m_fStartAngle = pTarget->getRotation();
}
void CCRotateBy::update(cocos2d::ccTime time)
{
2010-08-06 15:48:53 +08:00
// XXX: shall I add % 360
m_pTarget->setRotation(m_fStartAngle + m_fAngle * time);
}
CCIntervalAction* CCRotateBy::reverse(void)
{
2010-08-06 15:48:53 +08:00
return CCRotateBy::actionWithDuration(m_fDuration, -m_fAngle);
}
//
// MoveTo
//
CCMoveTo* CCMoveTo::actionWithDuration(cocos2d::ccTime duration, cocos2d::CGPoint position)
{
2010-08-06 15:48:53 +08:00
CCMoveTo *pMoveTo = new CCMoveTo();
pMoveTo->initWithDuration(duration, position);
pMoveTo->autorelease();
return pMoveTo;
}
2010-08-11 14:03:46 +08:00
bool CCMoveTo::initWithDuration(cocos2d::ccTime duration, cocos2d::CGPoint position)
{
2010-09-02 14:54:42 +08:00
if (CCIntervalAction::initWithDuration(duration))
2010-08-06 15:48:53 +08:00
{
m_endPosition = position;
2010-08-11 14:03:46 +08:00
return true;
2010-08-06 15:48:53 +08:00
}
2010-08-11 14:03:46 +08:00
return false;
}
NSObject* CCMoveTo::copyWithZone(cocos2d::NSZone *pZone)
{
2010-08-06 15:48:53 +08:00
NSZone* pNewZone = NULL;
CCMoveTo* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCMoveTo*)(pZone->m_pCopyObject);
2010-08-06 15:48:53 +08:00
}
else
{
pCopy = new CCMoveTo();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::copyWithZone(pZone);
2010-08-06 15:48:53 +08:00
pCopy->initWithDuration(m_fDuration, m_endPosition);
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
void CCMoveTo::startWithTarget(CCNode *pTarget)
2010-08-06 14:44:17 +08:00
{
2010-09-02 14:54:42 +08:00
CCIntervalAction::startWithTarget(pTarget);
m_startPosition = pTarget->getPosition();
2010-08-06 15:48:53 +08:00
m_delta = ccpSub(m_endPosition, m_startPosition);
2010-08-06 14:44:17 +08:00
}
void CCMoveTo::update(cocos2d::ccTime time)
{
m_pTarget->setPosition(ccp(m_startPosition.x + m_delta.x * time,
2010-08-06 15:48:53 +08:00
m_startPosition.y + m_delta.y * time));
}
//
// MoveBy
//
CCMoveBy* CCMoveBy::actionWithDuration(cocos2d::ccTime duration, cocos2d::CGPoint position)
{
2010-08-06 15:48:53 +08:00
CCMoveBy *pMoveBy = new CCMoveBy();
pMoveBy->initWithDuration(duration, position);
pMoveBy->autorelease();
return pMoveBy;
}
2010-08-11 14:03:46 +08:00
bool CCMoveBy::initWithDuration(cocos2d::ccTime duration, cocos2d::CGPoint position)
{
2010-08-06 15:48:53 +08:00
if (CCIntervalAction::initWithDuration(duration))
{
m_delta = position;
2010-08-11 14:03:46 +08:00
return true;
2010-08-06 15:48:53 +08:00
}
2010-08-11 14:03:46 +08:00
return false;
}
NSObject* CCMoveBy::copyWithZone(cocos2d::NSZone *pZone)
{
2010-08-06 15:48:53 +08:00
NSZone* pNewZone = NULL;
CCMoveBy* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCMoveBy*)(pZone->m_pCopyObject);
2010-08-06 15:48:53 +08:00
}
else
{
pCopy = new CCMoveBy();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCMoveTo::copyWithZone(pZone);
2010-08-06 15:48:53 +08:00
pCopy->initWithDuration(m_fDuration, m_delta);
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
void CCMoveBy::startWithTarget(CCNode *pTarget)
{
2010-08-09 16:27:36 +08:00
CGPoint dTmp = m_delta;
2010-09-02 14:54:42 +08:00
CCMoveTo::startWithTarget(pTarget);
2010-08-09 16:27:36 +08:00
m_delta = dTmp;
}
CCIntervalAction* CCMoveBy::reverse(void)
{
2010-08-09 16:27:36 +08:00
return CCMoveBy::actionWithDuration(m_fDuration, ccp(-m_delta.x, -m_delta.y));
}
//
// JumpBy
//
CCJumpBy* CCJumpBy::actionWithDuration(cocos2d::ccTime duration, cocos2d::CGPoint position, cocos2d::ccTime height, int jumps)
{
2010-08-09 16:27:36 +08:00
CCJumpBy *pJumpBy = new CCJumpBy();
pJumpBy->initWithDuration(duration, position, height, jumps);
pJumpBy->autorelease();
return pJumpBy;
}
2010-08-11 14:03:46 +08:00
bool CCJumpBy::initWithDuration(cocos2d::ccTime duration, cocos2d::CGPoint position, cocos2d::ccTime height, int jumps)
{
2010-09-02 14:54:42 +08:00
if (CCIntervalAction::initWithDuration(duration))
2010-08-09 16:27:36 +08:00
{
m_delta = position;
2010-08-12 17:01:51 +08:00
m_height = height;
2010-08-09 16:27:36 +08:00
m_nJumps = jumps;
2010-08-11 14:03:46 +08:00
return true;
2010-08-09 16:27:36 +08:00
}
2010-08-11 14:03:46 +08:00
return false;
}
NSObject* CCJumpBy::copyWithZone(cocos2d::NSZone *pZone)
{
2010-08-09 16:27:36 +08:00
NSZone* pNewZone = NULL;
CCJumpBy* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCJumpBy*)(pZone->m_pCopyObject);
2010-08-09 16:27:36 +08:00
}
else
{
pCopy = new CCJumpBy();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::copyWithZone(pZone);
2010-08-09 16:27:36 +08:00
pCopy->initWithDuration(m_fDuration, m_delta, m_height, m_nJumps);
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
void CCJumpBy::startWithTarget(CCNode *pTarget)
{
2010-09-02 14:54:42 +08:00
CCIntervalAction::startWithTarget(pTarget);
m_startPosition = pTarget->getPosition();
}
void CCJumpBy::update(cocos2d::ccTime time)
{
2010-08-09 16:27:36 +08:00
// parabolic jump (since v0.8.2)
ccTime frac = fmodf(time * m_nJumps, 1.0f);
ccTime y = m_height * 4 * frac * (1 - frac);
y += m_delta.y * time;
ccTime x = m_delta.x * time;
m_pTarget->setPosition(ccp(m_startPosition.x + x, m_startPosition.y + y));
}
CCIntervalAction* CCJumpBy::reverse(void)
{
2010-08-09 16:27:36 +08:00
return CCJumpBy::actionWithDuration(m_fDuration, ccp(-m_delta.x, -m_delta.y),
m_height, m_nJumps);
}
//
// JumpTo
//
2010-08-11 14:03:46 +08:00
CCJumpTo* CCJumpTo::actionWithDuration(cocos2d::ccTime duration, cocos2d::CGPoint position, cocos2d::ccTime height, int jumps)
{
CCJumpTo *pJumpTo = new CCJumpTo();
pJumpTo->initWithDuration(duration, position, height, jumps);
pJumpTo->autorelease();
return pJumpTo;
}
NSObject* CCJumpTo::copyWithZone(NSZone* pZone)
{
NSZone* pNewZone = NULL;
2010-08-12 17:01:51 +08:00
CCJumpTo* pCopy = NULL;
2010-08-11 14:03:46 +08:00
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCJumpTo*)(pZone->m_pCopyObject);
2010-08-11 14:03:46 +08:00
}
else
{
pCopy = new CCJumpTo();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCJumpBy::copyWithZone(pZone);
2010-08-11 14:03:46 +08:00
pCopy->initWithDuration(m_fDuration, m_delta, m_height, m_nJumps);
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
void CCJumpTo::startWithTarget(CCNode *pTarget)
{
2010-09-02 14:54:42 +08:00
CCJumpBy::startWithTarget(pTarget);
2010-08-09 16:27:36 +08:00
m_delta = ccp(m_delta.x - m_startPosition.x, m_delta.y - m_startPosition.y);
}
// Bezier cubic formula:
// ((1 - t) + t)3 = 1
// Expands to<74><6F>
// (1 - t)3 + 3t(1-t)2 + 3t2(1 - t) + t3 = 1
static inline float bezierat( float a, float b, float c, float d, ccTime t )
{
return (powf(1-t,3) * a +
3*t*(powf(1-t,2))*b +
3*powf(t,2)*(1-t)*c +
powf(t,3)*d );
}
//
// BezierBy
//
CCBezierBy* CCBezierBy::actionWithDuration(cocos2d::ccTime t, cocos2d::ccBezierConfig c)
{
2010-08-09 16:27:36 +08:00
CCBezierBy *pBezierBy = new CCBezierBy();
pBezierBy->initWithDuration(t, c);
pBezierBy->autorelease();
return pBezierBy;
}
2010-08-11 14:03:46 +08:00
bool CCBezierBy::initWithDuration(cocos2d::ccTime t, cocos2d::ccBezierConfig c)
{
2010-09-02 14:54:42 +08:00
if (CCIntervalAction::initWithDuration(t))
2010-08-09 16:27:36 +08:00
{
m_sConfig = c;
2010-08-11 14:03:46 +08:00
return true;
2010-08-09 16:27:36 +08:00
}
2010-08-11 14:03:46 +08:00
return false;
}
void CCBezierBy::startWithTarget(CCNode *pTarget)
{
2010-09-02 14:54:42 +08:00
CCIntervalAction::startWithTarget(pTarget);
m_startPosition = pTarget->getPosition();
}
2010-08-06 14:44:17 +08:00
NSObject* CCBezierBy::copyWithZone(cocos2d::NSZone *pZone)
{
2010-08-09 16:27:36 +08:00
NSZone* pNewZone = NULL;
CCBezierBy* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCBezierBy*)(pZone->m_pCopyObject);
2010-08-09 16:27:36 +08:00
}
else
{
pCopy = new CCBezierBy();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::copyWithZone(pZone);
2010-08-09 16:27:36 +08:00
pCopy->initWithDuration(m_fDuration, m_sConfig);
CCX_SAFE_DELETE(pNewZone);
return pCopy;
2010-08-06 14:44:17 +08:00
}
void CCBezierBy::update(cocos2d::ccTime time)
{
2010-08-09 16:27:36 +08:00
float xa = 0;
float xb = m_sConfig.controlPoint_1.x;
float xc = m_sConfig.controlPoint_2.x;
float xd = m_sConfig.endPosition.x;
float ya = 0;
float yb = m_sConfig.controlPoint_1.y;
float yc = m_sConfig.controlPoint_2.y;
float yd = m_sConfig.endPosition.y;
float x = bezierat(xa, xb, xc, xd, time);
float y = bezierat(ya, yb, yc, yd, time);
m_pTarget->setPosition(ccpAdd(m_startPosition, ccp(x, y)));
}
CCIntervalAction* CCBezierBy::reverse(void)
{
2010-08-09 16:27:36 +08:00
ccBezierConfig r;
r.endPosition = ccpNeg(m_sConfig.endPosition);
r.controlPoint_1 = ccpAdd(m_sConfig.controlPoint_2, ccpNeg(m_sConfig.endPosition));
r.controlPoint_2 = ccpAdd(m_sConfig.controlPoint_1, ccpNeg(m_sConfig.endPosition));
CCBezierBy *pAction = CCBezierBy::actionWithDuration(m_fDuration, r);
return pAction;
}
//
// BezierTo
//
2010-08-11 14:03:46 +08:00
CCBezierTo* CCBezierTo::actionWithDuration(ccTime t, ccBezierConfig c)
{
CCBezierTo *pBezierTo = new CCBezierTo();
pBezierTo->initWithDuration(t, c);
pBezierTo->autorelease();
return pBezierTo;
}
NSObject* CCBezierTo::copyWithZone(cocos2d::NSZone *pZone)
{
NSZone* pNewZone = NULL;
CCBezierBy* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCBezierTo*)(pZone->m_pCopyObject);
2010-08-11 14:03:46 +08:00
}
else
{
pCopy = new CCBezierTo();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCBezierBy::copyWithZone(pZone);
2010-08-11 14:03:46 +08:00
pCopy->initWithDuration(m_fDuration, m_sConfig);
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
void CCBezierTo::startWithTarget(CCNode *pTarget)
{
2010-09-02 14:54:42 +08:00
CCBezierBy::startWithTarget(pTarget);
2010-08-09 16:27:36 +08:00
m_sConfig.controlPoint_1 = ccpSub(m_sConfig.controlPoint_1, m_startPosition);
m_sConfig.controlPoint_2 = ccpSub(m_sConfig.controlPoint_2, m_startPosition);
m_sConfig.endPosition = ccpSub(m_sConfig.endPosition, m_startPosition);
}
//
// ScaleTo
//
CCScaleTo* CCScaleTo::actionWithDuration(cocos2d::ccTime duration, float s)
{
2010-08-09 16:27:36 +08:00
CCScaleTo *pScaleTo = new CCScaleTo();
pScaleTo->initWithDuration(duration, s);
pScaleTo->autorelease();
return pScaleTo;
}
2010-08-11 14:03:46 +08:00
bool CCScaleTo::initWithDuration(cocos2d::ccTime duration, float s)
{
2010-09-02 14:54:42 +08:00
if (CCIntervalAction::initWithDuration(duration))
2010-08-09 16:27:36 +08:00
{
m_fEndScaleX = s;
m_fEndScaleY = s;
2010-08-11 14:03:46 +08:00
return true;
2010-08-09 16:27:36 +08:00
}
2010-08-11 14:03:46 +08:00
return false;
}
CCScaleTo* CCScaleTo::actionWithDuration(cocos2d::ccTime duration, float sx, float sy)
{
2010-08-09 16:27:36 +08:00
CCScaleTo *pScaleTo = new CCScaleTo();
pScaleTo->initWithDuration(duration, sx, sy);
pScaleTo->autorelease();
return pScaleTo;
}
2010-08-11 14:03:46 +08:00
bool CCScaleTo::initWithDuration(cocos2d::ccTime duration, float sx, float sy)
{
2010-09-02 14:54:42 +08:00
if (CCIntervalAction::initWithDuration(duration))
2010-08-09 16:27:36 +08:00
{
m_fEndScaleX = sx;
m_fEndScaleY = sy;
2010-08-11 14:03:46 +08:00
return true;
2010-08-09 16:27:36 +08:00
}
2010-08-11 14:03:46 +08:00
return false;
}
NSObject* CCScaleTo::copyWithZone(cocos2d::NSZone *pZone)
{
2010-08-09 16:27:36 +08:00
NSZone* pNewZone = NULL;
CCScaleTo* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCScaleTo*)(pZone->m_pCopyObject);
2010-08-09 16:27:36 +08:00
}
else
{
pCopy = new CCScaleTo();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::copyWithZone(pZone);
2010-08-09 16:27:36 +08:00
pCopy->initWithDuration(m_fDuration, m_fEndScaleX, m_fEndScaleY);
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
void CCScaleTo::startWithTarget(CCNode *pTarget)
{
2010-09-02 14:54:42 +08:00
CCIntervalAction::startWithTarget(pTarget);
m_fStartScaleX = pTarget->getScaleX();
m_fStartScaleY = pTarget->getScaleY();
2010-08-09 16:27:36 +08:00
m_fDeltaX = m_fEndScaleX - m_fStartScaleX;
m_fDeltaY = m_fEndScaleY - m_fStartScaleY;
}
void CCScaleTo::update(cocos2d::ccTime time)
{
m_pTarget->setScaleX(m_fStartScaleX + m_fDeltaX * time);
m_pTarget->setScaleY(m_fStartScaleY + m_fDeltaY * time);
}
//
// ScaleBy
//
2010-08-11 14:03:46 +08:00
CCScaleBy* CCScaleBy::actionWithDuration(cocos2d::ccTime duration, float s)
{
CCScaleBy *pScaleBy = new CCScaleBy();
pScaleBy->initWithDuration(duration, s);
pScaleBy->autorelease();
return pScaleBy;
}
CCScaleBy* CCScaleBy::actionWithDuration(cocos2d::ccTime duration, float sx, float sy)
{
CCScaleBy *pScaleBy = new CCScaleBy();
pScaleBy->initWithDuration(duration, sx, sy);
pScaleBy->autorelease();
return pScaleBy;
}
NSObject* CCScaleBy::copyWithZone(cocos2d::NSZone *pZone)
{
NSZone* pNewZone = NULL;
CCScaleTo* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCScaleBy*)(pZone->m_pCopyObject);
2010-08-11 14:03:46 +08:00
}
else
{
pCopy = new CCScaleBy();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCScaleTo::copyWithZone(pZone);
2010-08-11 14:03:46 +08:00
pCopy->initWithDuration(m_fDuration, m_fEndScaleX, m_fEndScaleY);
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
void CCScaleBy::startWithTarget(CCNode *pTarget)
{
2010-09-02 14:54:42 +08:00
CCScaleTo::startWithTarget(pTarget);
2010-08-09 16:27:36 +08:00
m_fDeltaX = m_fStartScaleX * m_fEndScaleX - m_fStartScaleX;
m_fDeltaY = m_fStartScaleY * m_fEndScaleY - m_fStartScaleY;
}
CCIntervalAction* CCScaleBy::reverse(void)
{
2010-08-09 16:27:36 +08:00
return CCScaleBy::actionWithDuration(m_fDuration, 1 / m_fEndScaleX, 1 / m_fEndScaleY);
}
//
// Blink
//
CCBlink* CCBlink::actionWithDuration(cocos2d::ccTime duration, unsigned int uBlinks)
{
2010-08-09 16:27:36 +08:00
CCBlink *pBlink = new CCBlink();
pBlink->initWithDuration(duration, uBlinks);
pBlink->autorelease();
return pBlink;
}
2010-08-11 14:03:46 +08:00
bool CCBlink::initWithDuration(cocos2d::ccTime duration, unsigned int uBlinks)
{
2010-09-02 14:54:42 +08:00
if (CCIntervalAction::initWithDuration(duration))
2010-08-09 16:27:36 +08:00
{
m_nTimes = uBlinks;
2010-08-11 14:03:46 +08:00
return true;
2010-08-09 16:27:36 +08:00
}
2010-08-11 14:03:46 +08:00
return false;
}
NSObject* CCBlink::copyWithZone(cocos2d::NSZone *pZone)
{
2010-08-09 16:27:36 +08:00
NSZone* pNewZone = NULL;
CCBlink* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCBlink*)(pZone->m_pCopyObject);
2010-08-09 16:27:36 +08:00
}
else
{
pCopy = new CCBlink();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::copyWithZone(pZone);
2010-08-09 16:27:36 +08:00
pCopy->initWithDuration(m_fDuration, (unsigned int)m_nTimes);
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
void CCBlink::update(cocos2d::ccTime time)
{
2010-08-09 16:27:36 +08:00
ccTime slice = 1.0f / m_nTimes;
ccTime m = fmodf(time, slice);
m_pTarget->setIsVisible(m > slice / 2 ? true : false);
}
CCIntervalAction* CCBlink::reverse(void)
{
2010-08-09 16:27:36 +08:00
// return 'self'
return CCBlink::actionWithDuration(m_fDuration, m_nTimes);
}
//
// FadeIn
//
2010-08-11 14:03:46 +08:00
CCFadeIn* CCFadeIn::actionWithDuration(cocos2d::ccTime d)
{
CCFadeIn* pAction = new CCFadeIn();
pAction->initWithDuration(d);
pAction->autorelease();
return pAction;
}
NSObject* CCFadeIn::copyWithZone(cocos2d::NSZone *pZone)
{
NSZone* pNewZone = NULL;
CCFadeIn* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCFadeIn*)(pZone->m_pCopyObject);
2010-08-11 14:03:46 +08:00
}
else
{
pCopy = new CCFadeIn();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::copyWithZone(pZone);
2010-08-11 14:03:46 +08:00
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
void CCFadeIn::update(cocos2d::ccTime time)
{
CCRGBAProtocol *pRGBAProtocol = m_pTarget->convertToRGBAProtocol();
if (pRGBAProtocol)
{
pRGBAProtocol->setOpacity((GLubyte)(255 * time));
}
/*m_pTarget->setOpacity((GLubyte)(255 * time));*/
}
CCIntervalAction* CCFadeIn::reverse(void)
{
2010-08-09 16:27:36 +08:00
return CCFadeOut::actionWithDuration(m_fDuration);
}
//
// FadeOut
//
2010-08-11 14:03:46 +08:00
CCFadeOut* CCFadeOut::actionWithDuration(cocos2d::ccTime d)
{
CCFadeOut* pAction = new CCFadeOut();
pAction->initWithDuration(d);
pAction->autorelease();
return pAction;
}
NSObject* CCFadeOut::copyWithZone(cocos2d::NSZone *pZone)
{
NSZone* pNewZone = NULL;
CCFadeOut* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCFadeOut*)(pZone->m_pCopyObject);
2010-08-11 14:03:46 +08:00
}
else
{
pCopy = new CCFadeOut();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::copyWithZone(pZone);
2010-08-11 14:03:46 +08:00
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
void CCFadeOut::update(cocos2d::ccTime time)
{
CCRGBAProtocol *pRGBAProtocol = m_pTarget->convertToRGBAProtocol();
if (pRGBAProtocol)
{
pRGBAProtocol->setOpacity(GLubyte(255 * (1 - time)));
}
/*m_pTarget->setOpacity(GLubyte(255 * (1 - time)));*/
}
CCIntervalAction* CCFadeOut::reverse(void)
{
2010-08-09 16:27:36 +08:00
return CCFadeIn::actionWithDuration(m_fDuration);
}
//
// FadeTo
//
CCFadeTo* CCFadeTo::actionWithDuration(cocos2d::ccTime duration, GLubyte opacity)
{
2010-08-09 16:27:36 +08:00
CCFadeTo *pFadeTo = new CCFadeTo();
pFadeTo->initWithDuration(duration, opacity);
pFadeTo->autorelease();
return pFadeTo;
}
2010-08-11 14:03:46 +08:00
bool CCFadeTo::initWithDuration(cocos2d::ccTime duration, GLubyte opacity)
{
2010-09-02 14:54:42 +08:00
if (CCIntervalAction::initWithDuration(duration))
2010-08-09 16:27:36 +08:00
{
m_toOpacity = opacity;
2010-08-11 14:03:46 +08:00
return true;
2010-08-09 16:27:36 +08:00
}
2010-08-11 14:03:46 +08:00
return false;
}
NSObject* CCFadeTo::copyWithZone(cocos2d::NSZone *pZone)
{
2010-08-09 16:27:36 +08:00
NSZone* pNewZone = NULL;
CCFadeTo* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCFadeTo*)(pZone->m_pCopyObject);
2010-08-09 16:27:36 +08:00
}
else
{
pCopy = new CCFadeTo();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::copyWithZone(pZone);
2010-08-09 16:27:36 +08:00
pCopy->initWithDuration(m_fDuration, m_toOpacity);
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
void CCFadeTo::startWithTarget(CCNode *pTarget)
{
2010-09-02 14:54:42 +08:00
CCIntervalAction::startWithTarget(pTarget);
2010-08-09 16:27:36 +08:00
CCRGBAProtocol *pRGBAProtocol = pTarget->convertToRGBAProtocol();
if (pRGBAProtocol)
{
m_fromOpacity = pRGBAProtocol->getOpacity();
}
/*m_fromOpacity = pTarget->getOpacity();*/
}
void CCFadeTo::update(cocos2d::ccTime time)
{
CCRGBAProtocol *pRGBAProtocol = m_pTarget->convertToRGBAProtocol();
if (pRGBAProtocol)
{
pRGBAProtocol->setOpacity((GLubyte)(m_fromOpacity + (m_toOpacity - m_fromOpacity) * time));
}
/*m_pTarget->setOpacity((GLubyte)(m_fromOpacity + (m_toOpacity - m_fromOpacity) * time));*/
}
//
// TintTo
//
CCTintTo* CCTintTo::actionWithDuration(cocos2d::ccTime duration, GLubyte red, GLubyte green, GLubyte blue)
{
2010-08-09 16:27:36 +08:00
CCTintTo *pTintTo = new CCTintTo();
pTintTo->initWithDuration(duration, red, green, blue);
pTintTo->autorelease();
return pTintTo;
}
2010-08-11 14:03:46 +08:00
bool CCTintTo::initWithDuration(cocos2d::ccTime duration, GLubyte red, GLubyte green, GLubyte blue)
{
2010-09-02 14:54:42 +08:00
if (CCIntervalAction::initWithDuration(duration))
2010-08-09 16:27:36 +08:00
{
m_to = ccc3(red, green, blue);
2010-08-11 14:03:46 +08:00
return true;
2010-08-09 16:27:36 +08:00
}
2010-08-11 14:03:46 +08:00
return false;
}
NSObject* CCTintTo::copyWithZone(cocos2d::NSZone *pZone)
{
2010-08-09 16:27:36 +08:00
NSZone* pNewZone = NULL;
CCTintTo* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCTintTo*)(pZone->m_pCopyObject);
2010-08-09 16:27:36 +08:00
}
else
{
pCopy = new CCTintTo();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::copyWithZone(pZone);
2010-08-09 16:27:36 +08:00
pCopy->initWithDuration(m_fDuration, m_to.r, m_to.g, m_to.b);
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
void CCTintTo::startWithTarget(CCNode *pTarget)
{
2010-09-02 14:54:42 +08:00
CCIntervalAction::startWithTarget(pTarget);
CCRGBAProtocol *pRGBAProtocol = m_pTarget->convertToRGBAProtocol();
if (pRGBAProtocol)
{
m_from = pRGBAProtocol->getColor();
}
/*m_from = pTarget->getColor();*/
}
void CCTintTo::update(cocos2d::ccTime time)
{
CCRGBAProtocol *pRGBAProtocol = m_pTarget->convertToRGBAProtocol();
if (pRGBAProtocol)
{
pRGBAProtocol->setColor(ccc3(GLubyte(m_from.r + (m_to.r - m_from.r) * time),
(GLbyte)(m_from.g + (m_to.g - m_from.g) * time),
(GLbyte)(m_from.b + (m_to.b - m_from.b) * time)));
}
}
//
// TintBy
//
CCTintBy* CCTintBy::actionWithDuration(cocos2d::ccTime duration, GLshort deltaRed, GLshort deltaGreen, GLshort deltaBlue)
{
2010-08-09 16:27:36 +08:00
CCTintBy *pTintBy = new CCTintBy();
pTintBy->initWithDuration(duration, deltaRed, deltaGreen, deltaBlue);
pTintBy->autorelease();
return pTintBy;
}
2010-08-11 14:03:46 +08:00
bool CCTintBy::initWithDuration(cocos2d::ccTime duration, GLshort deltaRed, GLshort deltaGreen, GLshort deltaBlue)
{
2010-09-02 14:54:42 +08:00
if (CCIntervalAction::initWithDuration(duration))
2010-08-09 16:27:36 +08:00
{
m_deltaR = deltaRed;
m_deltaG = deltaGreen;
m_deltaB = deltaBlue;
2010-08-11 14:03:46 +08:00
return true;
2010-08-09 16:27:36 +08:00
}
2010-08-11 14:03:46 +08:00
return false;
}
NSObject* CCTintBy::copyWithZone(cocos2d::NSZone *pZone)
{
2010-08-09 16:27:36 +08:00
NSZone* pNewZone = NULL;
CCTintBy* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCTintBy*)(pZone->m_pCopyObject);
2010-08-09 16:27:36 +08:00
}
else
{
pCopy = new CCTintBy();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::copyWithZone(pZone);
2010-08-09 16:27:36 +08:00
pCopy->initWithDuration(m_fDuration, (GLubyte)m_deltaR, (GLubyte)m_deltaG, (GLubyte)m_deltaB);
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
void CCTintBy::startWithTarget(CCNode *pTarget)
{
2010-09-02 14:54:42 +08:00
CCIntervalAction::startWithTarget(pTarget);
2010-08-09 16:27:36 +08:00
CCRGBAProtocol *pRGBAProtocol = pTarget->convertToRGBAProtocol();
if (pRGBAProtocol)
{
ccColor3B color = pRGBAProtocol->getColor();
m_fromR = color.r;
m_fromG = color.g;
m_fromB = color.b;
}
}
void CCTintBy::update(cocos2d::ccTime time)
{
CCRGBAProtocol *pRGBAProtocol = m_pTarget->convertToRGBAProtocol();
if (pRGBAProtocol)
{
pRGBAProtocol->setColor(ccc3((GLubyte)(m_fromR + m_deltaR * time),
(GLubyte)(m_fromG + m_deltaG * time),
(GLubyte)(m_fromB + m_deltaB * time)));
}
}
CCIntervalAction* CCTintBy::reverse(void)
{
2010-08-12 17:01:51 +08:00
return CCTintBy::actionWithDuration(m_fDuration, -m_deltaR, -m_deltaG, -m_deltaB);
}
//
// DelayTime
//
2010-08-11 14:03:46 +08:00
CCDelayTime* CCDelayTime::actionWithDuration(cocos2d::ccTime d)
{
CCDelayTime* pAction = new CCDelayTime();
pAction->initWithDuration(d);
pAction->autorelease();
return pAction;
}
NSObject* CCDelayTime::copyWithZone(cocos2d::NSZone *pZone)
{
NSZone* pNewZone = NULL;
CCDelayTime* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCDelayTime*)(pZone->m_pCopyObject);
2010-08-11 14:03:46 +08:00
}
else
{
pCopy = new CCDelayTime();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::copyWithZone(pZone);
2010-08-11 14:03:46 +08:00
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
void CCDelayTime::update(cocos2d::ccTime time)
{
2010-08-09 16:27:36 +08:00
return;
}
CCIntervalAction* CCDelayTime::reverse(void)
{
2010-08-09 16:27:36 +08:00
return CCDelayTime::actionWithDuration(m_fDuration);
}
//
// ReverseTime
//
CCReverseTime* CCReverseTime::actionWithAction(cocos2d::CCFiniteTimeAction *pAction)
{
2010-08-09 16:27:36 +08:00
// casting to prevent warnings
CCReverseTime *pReverseTime = new CCReverseTime();
pReverseTime->initWithAction(pAction);
pReverseTime->autorelease();
return pReverseTime;
}
2010-08-11 14:03:46 +08:00
bool CCReverseTime::initWithAction(cocos2d::CCFiniteTimeAction *pAction)
{
2010-09-02 14:54:42 +08:00
if (CCIntervalAction::initWithDuration(pAction->getDuration()))
2010-08-09 16:27:36 +08:00
{
m_pOther = pAction;
pAction->retain();
2010-08-11 14:03:46 +08:00
return true;
2010-08-09 16:27:36 +08:00
}
2010-08-11 14:03:46 +08:00
return false;
}
NSObject* CCReverseTime::copyWithZone(cocos2d::NSZone *pZone)
{
2010-08-09 16:27:36 +08:00
NSZone* pNewZone = NULL;
CCReverseTime* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCReverseTime*)(pZone->m_pCopyObject);
2010-08-09 16:27:36 +08:00
}
else
{
pCopy = new CCReverseTime();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::copyWithZone(pZone);
2010-08-09 16:27:36 +08:00
pCopy->initWithAction((CCFiniteTimeAction*)(m_pOther->copy()->autorelease()));
2010-08-09 16:27:36 +08:00
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
CCReverseTime::~CCReverseTime(void)
{
2010-08-09 16:27:36 +08:00
m_pOther->release();
}
void CCReverseTime::startWithTarget(CCNode *pTarget)
{
2010-09-02 14:54:42 +08:00
CCIntervalAction::startWithTarget(pTarget);
2010-08-09 16:27:36 +08:00
m_pOther->startWithTarget(pTarget);
}
void CCReverseTime::stop(void)
{
2010-08-09 16:27:36 +08:00
m_pOther->stop();
2010-09-02 14:54:42 +08:00
CCIntervalAction::stop();
}
void CCReverseTime::update(cocos2d::ccTime time)
{
2010-08-09 16:27:36 +08:00
m_pOther->update(1 - time);
}
CCIntervalAction* CCReverseTime::reverse(void)
{
return (CCIntervalAction*)(m_pOther->copy()->autorelease());
}
//
// Animate
//
CCAnimate* CCAnimate::actionWithAnimation(cocos2d::CCAnimation *pAnimation)
{
2010-08-09 16:27:36 +08:00
CCAnimate *pAnimate = new CCAnimate();
pAnimate->initWithAnimation(pAnimation, true);
pAnimate->autorelease();
return pAnimate;
}
2010-08-11 14:03:46 +08:00
bool CCAnimate::initWithAnimation(cocos2d::CCAnimation *pAnimation)
{
2010-08-09 16:27:36 +08:00
assert(pAnimation != NULL);
return initWithAnimation(pAnimation, true);
}
CCAnimate* CCAnimate::actionWithAnimation(cocos2d::CCAnimation *pAnimation, bool bRestoreOriginalFrame)
{
2010-08-09 16:27:36 +08:00
CCAnimate *pAnimate = new CCAnimate();
pAnimate->initWithAnimation(pAnimation, bRestoreOriginalFrame);
pAnimate->autorelease();
return pAnimate;
}
2010-08-11 14:03:46 +08:00
bool CCAnimate::initWithAnimation(cocos2d::CCAnimation *pAnimation, bool bRestoreOriginalFrame)
{
2010-08-09 16:27:36 +08:00
assert(pAnimation);
2010-09-02 14:54:42 +08:00
if (CCIntervalAction::initWithDuration(pAnimation->getFrames()->count() * pAnimation->getDelay()))
2010-08-09 16:27:36 +08:00
{
m_bRestoreOriginalFrame = bRestoreOriginalFrame;
m_pAnimation = pAnimation;
2010-08-12 17:01:51 +08:00
m_pAnimation->retain();
2010-08-09 16:27:36 +08:00
m_pOrigFrame = NULL;
2010-08-11 14:03:46 +08:00
return true;
2010-08-09 16:27:36 +08:00
}
2010-08-11 14:03:46 +08:00
return false;
}
CCAnimate* CCAnimate::actionWithDuration(cocos2d::ccTime duration, cocos2d::CCAnimation *pAnimation, bool bRestoreOriginalFrame)
{
2010-08-09 16:27:36 +08:00
CCAnimate *pAnimate = new CCAnimate();
pAnimate->initWithDuration(duration, pAnimation, bRestoreOriginalFrame);
pAnimate->autorelease();
return pAnimate;
}
2010-08-11 14:03:46 +08:00
bool CCAnimate::initWithDuration(cocos2d::ccTime duration, cocos2d::CCAnimation *pAnimation, bool bRestoreOriginalFrame)
{
2010-08-09 16:27:36 +08:00
assert(pAnimation != NULL);
2010-09-02 14:54:42 +08:00
if (CCIntervalAction::initWithDuration(duration))
2010-08-09 16:27:36 +08:00
{
m_bRestoreOriginalFrame = bRestoreOriginalFrame;
m_pAnimation = pAnimation;
2010-08-12 17:01:51 +08:00
m_pAnimation->retain();
2010-08-09 16:27:36 +08:00
m_pOrigFrame = NULL;
2010-08-11 14:03:46 +08:00
return true;
2010-08-09 16:27:36 +08:00
}
2010-08-11 14:03:46 +08:00
return false;
}
NSObject* CCAnimate::copyWithZone(cocos2d::NSZone *pZone)
{
2010-08-09 16:27:36 +08:00
NSZone* pNewZone = NULL;
CCAnimate* pCopy = NULL;
if(pZone && pZone->m_pCopyObject)
{
//in case of being called at sub class
pCopy = (CCAnimate*)(pZone->m_pCopyObject);
2010-08-09 16:27:36 +08:00
}
else
{
pCopy = new CCAnimate();
pZone = pNewZone = new NSZone(pCopy);
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::copyWithZone(pZone);
2010-08-09 16:27:36 +08:00
pCopy->initWithDuration(m_fDuration, m_pAnimation, m_bRestoreOriginalFrame);
CCX_SAFE_DELETE(pNewZone);
return pCopy;
}
CCAnimate::~CCAnimate(void)
{
2010-08-12 17:01:51 +08:00
CCX_SAFE_RELEASE(m_pAnimation);
CCX_SAFE_RELEASE(m_pOrigFrame);
}
void CCAnimate::startWithTarget(CCNode *pTarget)
{
2010-09-02 14:54:42 +08:00
CCIntervalAction::startWithTarget(pTarget);
CCSprite *pSprite = (CCSprite*)(pTarget);
2010-08-09 16:27:36 +08:00
2010-08-11 18:15:52 +08:00
CCX_SAFE_RELEASE(m_pOrigFrame);
2010-08-09 16:27:36 +08:00
if (m_bRestoreOriginalFrame)
{
m_pOrigFrame = pSprite->displayedFrame();
m_pOrigFrame->retain();
}
}
void CCAnimate::stop(void)
{
2010-08-09 16:27:36 +08:00
if (m_bRestoreOriginalFrame)
{
((CCSprite*)(m_pTarget))->setDisplayFrame(m_pOrigFrame);
2010-08-09 16:27:36 +08:00
}
2010-09-02 14:54:42 +08:00
CCIntervalAction::stop();
}
void CCAnimate::update(cocos2d::ccTime time)
{
2010-08-09 16:27:36 +08:00
NSMutableArray<CCSpriteFrame*> *pFrames = m_pAnimation->getFrames();
unsigned int numberOfFrames = pFrames->count();
2010-08-12 17:01:51 +08:00
unsigned int idx = (unsigned int)(time * numberOfFrames);
2010-08-09 16:27:36 +08:00
if (idx >= numberOfFrames)
{
idx = numberOfFrames - 1;
}
CCSprite *pSprite = (CCSprite*)(m_pTarget);
2010-08-09 16:27:36 +08:00
if (! pSprite->isFrameDisplayed(pFrames->getObjectAtIndex(idx)))
{
pSprite->setDisplayFrame(pFrames->getObjectAtIndex(idx));
}
}
CCIntervalAction* CCAnimate::reverse(void)
{
2010-08-09 16:27:36 +08:00
NSMutableArray<CCSpriteFrame*> *pOldArray = m_pAnimation->getFrames();
NSMutableArray<CCSpriteFrame*> *pNewArray = new NSMutableArray<CCSpriteFrame*>(pOldArray->count());
if (pOldArray->count() > 0)
{
CCSpriteFrame *pElement;
NSMutableArray<CCSpriteFrame*>::NSMutableArrayRevIterator iter;
for (iter = pOldArray->rbegin(); iter != pOldArray->rend(); iter++)
{
pElement = *iter;
if (! pElement)
{
break;
}
pNewArray->addObject((CCSpriteFrame*)(pElement->copy()->autorelease()));
2010-08-09 16:27:36 +08:00
}
}
CCAnimation *pNewAnim = CCAnimation::animationWithName(m_pAnimation->getName(),
m_pAnimation->getDelay(), pNewArray);
pNewArray->release();
return CCAnimate::actionWithDuration(m_fDuration, pNewAnim, m_bRestoreOriginalFrame);
}
}