How to stop animate immediately?

Hi everyone,
I’m newbie to cocos2d-x game development. (sorry, I don’t speak english very well.)

I use keyboard EventListener, and I design if user push Left arrow button, My chracter start moving to left, also when user release left arrow button, my chracter will stop immediately.

So I implemented as follows code, but when I left arrow button released move action is stop immediately, but character’s animate didn’t stop immediately until animation’s all Frame is looped.

void GameScene::onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event_unused)
{

	auto sprMan = (Sprite*)this->getChildByTag(TAG_SPRITE_MAN);
	auto sprBlock = (Sprite*)this->getChildByTag(TAG_SPRITE_BLOCK);



	switch (keyCode)
	{
	case EventKeyboard::KeyCode::KEY_LEFT_ARROW:				// 왼쪽 방향키를 눌렀을 때.
	{
		auto action_0 = MoveBy::create(0.8, Point(-50, 0));
		auto action_1 = (Animate *)Director::getInstance()->getActionManager()->getActionByTag(TAG_ANIMATE_MAN, this);
		auto action_2 = Spawn::create(action_0, action_1,NULL);
		auto action_3 = RepeatForever::create(action_2);
		action_3->setTag(TAG_ACTION_MAN_LMOVE);
		sprMan->runAction(action_3);

		if (isTurnLeft != true)
		{
			sprMan->setFlippedX(true);
			isTurnLeft = true;
			isTurnRight = false;
		}

		isTurnLeft = true;
		isTurnRight = false;
		isMove = true;
		break;
	}
	case EventKeyboard::KeyCode::KEY_RIGHT_ARROW:				// 오른쪽 방향키를 눌렀을 때.
	{
		auto action_0 = MoveBy::create(0.8, Point(50, 0));		// 애니메이션 전프레임 반복 주기가 0.8이므로 이동 소요 시간도 똑같이 설정함.
		auto action_1 = (Animate *)Director::getInstance()->getActionManager()->getActionByTag(TAG_ANIMATE_MAN, this);;
		auto action_2 = Spawn::create(action_0, action_1, NULL);
		auto action_3 = RepeatForever::create(action_2);
		action_3->setTag(TAG_ACTION_MAN_RMOVE);
		sprMan->runAction(action_3);

		if (isTurnRight != true)
		{
			sprMan->setFlippedX(false);
			isTurnLeft = false;
			isTurnRight = true;
		}
		isTurnLeft = false;
		isTurnRight = true;
		isMove = true;
		break;
	}
	}
}


// 키보드 버튼이 떼졌을 때 호출됨
void GameScene::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event_unused)
{

	auto sprMan = (Sprite*)this->getChildByTag(TAG_SPRITE_MAN);
	auto sprBlock = (Sprite*)this->getChildByTag(TAG_SPRITE_BLOCK);


	switch (keyCode)
	{
	case EventKeyboard::KeyCode::KEY_LEFT_ARROW:				// 왼쪽 방향키 버튼이 떼졌을 때.
	{
		auto action_0 = (Action*)sprMan->getActionByTag(TAG_ACTION_MAN_LMOVE);
		sprMan->getActionManager()->removeAction(action_0);
		isMove = false;
		break;
	}
	case EventKeyboard::KeyCode::KEY_RIGHT_ARROW:				// 오른쪽 방향키 버튼이 떼졌을 때.
	{
		auto action_0 = (Action*)sprMan->getActionByTag(TAG_ACTION_MAN_RMOVE);
		sprMan->getActionManager()->removeAction(action_0);
	
		isMove = false;
		break;
	}
	}
}

How stop immediately my animate action?
I already tried removeAction, pauseTarget, stop(), …etc.

Please let me know solution, thanks you :slight_smile:

CCNode::stopAllActions()

thanks for your reply, but that is stop All action. I want stop sepcific action…

Maybe you can give a TAG for a spec action, and find it with the TAG again, then stop.

I’m already use Tag. Please see my code

Oh, i see.
And what happens if you stop it before remove?

I don’t use stop… maybe if you recommand stop method, that is same happen when I remove action.

Try to stop action not by tag?

How? I think action is inited another method, so that action is can call from only tag, didn’t it?

auto action_0 = MoveBy::create(0.8, Point(-50, 0));
auto action_1 = (Animate *)Director::getInstance()->getActionManager()->getActionByTag(TAG_ANIMATE_MAN, this);
auto action_2 = Spawn::create(action_0, action_1,NULL);
auto action_3 = RepeatForever::create(action_2);
sprMan->runAction(action_3);
_action_3 = action_3; // keep it in member variable
....

sprMan->stopAction(_action_3); // stop it by action instance

Thanks, but that is same happen. why cocos2d-x is can’t resolve this problem…

Try :
SprMan->stopActionByTag(TAG_ACTION_MAN_RMOVE);

Instead :
sprMan->getActionManager()->removeAction(action_0);

1 Like

@PumpkinSoup I believe what @sevent7 provided should take care of your issue. Please update us.

Thanks, but I tried that already… sigh…

Let me try and get this to work in a simple example.

auto action_1 = (Animate *)Director::getInstance()->getActionManager()->getActionByTag(TAG_ANIMATE_MAN, this);

As you pass this to getActionByTag, that means this action’s target is GameScene instead of sprMan, are you sure this is OK?