Hello I have checked this in two projects and the problem occurs in both.
I overread update method so I can see exact position at each loop. Code of the program is shown below:
void HelloWorld::update(float dt)
{
CCLOG("%f",this->sprite->getPosition().x);
}
.
void Helloworld::init()
{
this->sprite = Sprite::create("CloseNormal.png");
this->sprite->setPosition(100, 100);
auto callback = CallFunc::create(CC_CALLBACK_0(HelloWorld::callback, this));
auto action = RepeatForever::create(Sequence::create(MoveTo::create(1.0f, Point(116, 100)), callback, nullptr));
this->sprite->runAction(action);
this->addChild(this->sprite);
}
.
void HelloWorld::callback()
{
this->sprite->stopAllActions();
this->sprite->setPosition(Point(50, 100)); <-- causes problem
}
If I just stopAllActions in HelloWorld::callback method whithout setting Position, sprite stops at exact position but if I use setPosition it stops at 50.0345, 52.4355 etc… very random. Have you got an idea how to solve this ?
P.S when I use moveBy instead of moveTo it couses problem even without setPosition
Hi @piess105,
Why are you using RepeatForever when you’re stopping all the actions in your callback()?
Because you’re using RepeatForever, the actions inside it repeats after it’s finished. But because you’re calling stopAllActions inside one of the action contained in RepeatForever it has to remove itself from the target; but before it does, it has to finish its update method for that tick and in effect call the step method of all ActionInterval actions it contains. That’s why you’re getting additional value to your position after setting it. This is just my explanation after looking at the engine code.
Now for the reason why this is happening, I don’t really know. But there’s a comment in code involve which says this:
// The currentAction told the node to remove it. To prevent the action from
// accidentally deallocating itself before finishing its step, we retained
// it. Now that step is done, it's safe to release it.
I can only assume that it has something to do with preventing nullptr exception or memory leak.
Now, to solve your problem, just remove the RepeatForever. (I mean, you’re stopping the action anyway.)
Or if you don’t want to remove the RepeatForever, run the Place action instead of calling setPosition like so:
void HelloWorld::callback()
{
this->sprite->stopAllActions();
this->sprite->runAction(Place::create(Point(50.f, 100.f)));
}
This works because Place action will be in the action queue and will be called after the MoveTo action.
These are all well, but I’m just curious what are you trying to achieve here, as maybe there is a better way.
Nonetheless, hope this helps.
2 Likes
good observation 
yes, this might be the case exactly.
yeah it helped thank you so much. It’s just an example of code I did not want to copy all.