Hi there
CCRepeat has bug with repeat count 99 or 9999
For example my action
CCRepeat(CCSequence::createWithTwoActions( move_30_x , move_-30_x),99)
And now it stops on first action from sequence.
Example with position of node
On start
position = 0
now we run action
position = 30 # repeat 1
position = 0 # repeat 1
position = 30 # repeat 2
position = 0 # repeat 2
…
position = 30 # repeat 99
Pull request https://github.com/cocos2d/cocos2d-x/pull/5519
OK simply don’t use CCRepeat for such things it gives bad results not only for 99. I leave it for some time and still i have such thing
position = 30 # repeat XYZ
position = 0 # repeat XYZ
position = 30 # repeat XYZ + 1
position = 60 # repeat XYZ + 2 <------------------
position = 30 # repeat XYZ + 2
position = 60 # repeat XYZ + 3
position = 30 # repeat XYZ + 3
…
position = 90 # repeat XY
position = 60 # repeat XY
and so on
@gelldur
Could you paste some demo codes?
Thanks.
{
CCSprite* pSprite = CCSprite::create(R::Sprite::GUI_ARROW);
addChild(pSprite);
pSprite->setPosition(ccp(100,100));
pSprite->runAction(CCRepeat::create(CCSequence::createWithTwoActions( CCMoveBy::create(0.05F,ccp(130,0)) ,CCMoveBy::create(0.05F,ccp(-130,0))),99));
}
For example we start in point (0,0) and it stops in (130,0) it should stop in (0,0) but if you change times if CCMoveBy and distance you will see something odd that sprite starts walking to right edge of screen but it depends on time of CCMoveBy i think and repeat count
in this example arrow start walking to right
{
CCSprite* pSprite = CCSprite::create(R::Sprite::GUI_ARROW);
addChild(pSprite);
pSprite->setPosition(ccp(100,100));
pSprite->runAction(CCRepeat::create(CCSequence::createWithTwoActions( CCMoveBy::create(0.02F,ccp(130,0)) ,CCMoveBy::create(0.02F,ccp(-130,0))),11099));
}
My implementation of CCRepeat it works correctly but you can’t do such stuff like you can do with oryginal CCRepeat like Easing. The reason of this is in update method. But for what i use it i don’t need it
Repeat.h
/** @brief Repeats an action a number of times.
* To repeat an action forever use the RepeatForever action.
*/
class Repeat : public CCActionInterval
{
typedef CCActionInterval inherited;
public:
/** creates a Repeat action. Times is an unsigned integer between 1 and pow(2,30) */
static Repeat* create( CCFiniteTimeAction* pAction, unsigned int times )
{
Repeat* pRet = new Repeat();
if( pRet && pRet->initWithAction( pAction, times ) )
{
pRet->autorelease();
return pRet;
}
CC_SAFE_DELETE( pRet );
return pRet = nullptr;
}
/** initializes a Repeat action. Times is an unsigned integer between 1 and pow(2,30) */
bool initWithAction( CCFiniteTimeAction* pAction, unsigned int times );
virtual ~Repeat();
virtual CCObject* copyWithZone( CCZone* pZone );
virtual void startWithTarget( CCNode* pTarget );
virtual void stop();
virtual void step( float dt );
virtual void update( float dt );
virtual bool isDone();
virtual CCActionInterval* reverse();
inline void setInnerAction( CCFiniteTimeAction* pAction )
{
if( m_pInnerAction != pAction )
{
CC_SAFE_RETAIN( pAction );
CC_SAFE_RELEASE( m_pInnerAction );
m_pInnerAction = pAction;
}
}
CCFiniteTimeAction* getInnerAction()
{
return m_pInnerAction;
}
private:
unsigned int m_times;
unsigned int m_total;
CCFiniteTimeAction* m_pInnerAction;
bool m_isActionInstant;
Repeat();
};
Repeat.cpp
Repeat::Repeat() :
m_times( 0 )
, m_total( 0 )
, m_pInnerAction( nullptr )
, m_isActionInstant( false )
{
}
Repeat::~Repeat()
{
CC_SAFE_RELEASE( m_pInnerAction );
}
bool Repeat::initWithAction( CCFiniteTimeAction* pAction, unsigned int times )
{
float d = pAction->getDuration() * times;
if( inherited::initWithDuration( d ) == false )
{
return false;
}
m_times = times;
m_pInnerAction = pAction;
pAction->retain();
m_isActionInstant = dynamic_cast<CCActionInstant*>( pAction ) ? true : false;
//an instant action needs to be executed one time less in the update method since it uses startWithTarget to execute the action
if( m_isActionInstant )
{
m_times -= 1;
}
return true;
}
CCObject* Repeat::copyWithZone( CCZone* pZone )
{
//Do not use
assert( false );
return nullptr;
}
void Repeat::startWithTarget( CCNode* pTarget )
{
inherited::startWithTarget( pTarget );
m_total = 0;
m_pInnerAction->startWithTarget( pTarget );
}
void Repeat::stop( void )
{
inherited::stop();
m_pInnerAction->stop();
}
void Repeat::update( float dt )
{
if( dt == 1 )
{
m_pInnerAction->update( 1 );
m_pInnerAction->stop();
++m_total;
return;
}
step( CCDirector::sharedDirector()->getDeltaTime() );
}
void Repeat::step( float dt )
{
m_pInnerAction->step( dt );
if( m_pInnerAction->isDone() )
{
m_pInnerAction->stop();
m_pInnerAction->startWithTarget( m_pTarget );
++m_total;
}
}
bool Repeat::isDone( void )
{
return m_total >= m_times;
}
CCActionInterval* Repeat::reverse( void )
{
return Repeat::create( m_pInnerAction->reverse(), m_times );
}