ctapp1
ctapp1

Reputation: 596

multiple nodes in one action sequence

I haven't found a way to do this yet, all the methods I have found don't seem to work. I am trying call two actions from two different sprites in one sequence. Basically I need to call a second action after the first action is finished, but these actions have different nodes/sprites. This is what I have now but I get an error.

void Objects::function(cocos2d::Layer *layer)
{

auto object1 = Sprite::create("object1.png");
auto object2 = Sprite::create("object2.png");
...
...
layer->addChild(object1);
...
...
layer->addChild(object2);

auto object1StartMove = MoveBy::create(3, Point (50, 100));
auto object2Move = MoveBy::create(3, Point ( 30, 160));
auto object1FinishMove = MoveBy::create(3, Point (100, 50));

 auto actionSequenceObject2 = Sequence::create(object2Move, RemoveSelf::create(), NULL);
 auto actionSequenceObject1 = Sequence::create(object1StartMove,CallFunc::create(
 [&]() { 
 object2->runAction(actionSequenceObject2);
 }),object1FinishMove,RemoveSelf::create(), NULL);

 object1->runAction(actionSequence); 

So I need to do this in order: Sprite1 moves somewhere on the screen, sprite2 then moves somewhere on the screen, sprite1 then moves somewhere else on the screen. These cant happen at the same time.

Thanks

Upvotes: 0

Views: 779

Answers (4)

ctapp1
ctapp1

Reputation: 596

Thanks for answers everyone I am sure your methods work as well but this is what I did and it works. Instead of calling my object2->runAction directly from the main sequence, I made a new function and called object2->runAction from there. Then within the main sequence in the first function I called the second function and everything ran smoothly. If someone could shed some light on why this works that would be great.

void Objects::function1(cocos2d::Layer *layer)
{

object1 = Sprite::create("object1.png");
object2 = Sprite::create("object2.png");
...
...
layer->addChild(object1);
...
...
layer->addChild(object2);

auto object1StartMove = MoveBy::create(3, Point (50, 100));
auto object1FinishMove = MoveBy::create(3, Point (100, 50));

auto actionSequenceObject1 =    Sequence::create(object1StartMove,CallFunc::create(
[&]() { 
function2(layer);
}),object1FinishMove,RemoveSelf::create(), NULL);

object1->runAction(actionSequenceObject1); 

}

void Objects::function2(cocos2d::Layer *layer)
{
...
...

auto object2Move = MoveBy::create(3, Point ( 30, 160));

auto actionSequenceObject2 = Sequence::create(object2Move,   RemoveSelf::create(), NULL);

object2->runAction(actionSequenceObject2); 

}

Upvotes: 0

Chris Becke
Chris Becke

Reputation: 780

At the point in a project where you are starting to try to sequence multiple nodes, the facility of ActionTimeline - and using Cocosstudio 2 to create them, become increasingly relevant.

The ActionTimeline mechanisim itself is a tad overkill for this very simple example, but in essence - assuming you don't just lay your scene and timelines out in Cocosstudio - what you could do is create a cocosstudio::timeline::Timeline object, to which you would attach a number of cocosstudio::timeline::Frame's - each specifying an action to be performed on a node in the scene graph.

Then create an ActionTimeline object from the Timeline and run that as an action on "the" root node of your scene, and it will play the timeline out, triggering actions on all the child nodes.

Upvotes: 1

Filled Stacks
Filled Stacks

Reputation: 4346

Hi I used the following sequence to replicate what you are describing in your question. I have tested it and it works.

auto objectOneMovementSequence = Sequence::create(
     MoveTo::create(1.0f, Vec2(100, 50)),
     CallFunc::create([object2]()
     {
        object2->runAction(MoveTo::create(1.0f, Vec2(100, 0)));
     }),
     DelayTime::create(1.0f),
     MoveTo::create(1.0f, Vec2()),
     NULL);

object1->runAction(objectOneMovementSequence);

Instead of calling a different sequence in your callback just run the action you need to run using a delay time after to account for the time it will take for your second action to complete. This works on my side. Let me know if it's not the intended result you are looking for.

Upvotes: 2

Makalele
Makalele

Reputation: 7521

If you want use the same action on more than one sprite you have to use action->clone();

If you want to use one action after another you can:

a) delay second action by time of first action (DelayTime::create(t))

b) call a function which creates and plays second action after first one ends.

If you need to do it more than once I'd go for b) and easiest solution:

void Objects::anim1(){
    auto action = Sequence::create(..., CallFunc::create([&](){anim2(); }), NULL);
    object1->runAction(action);
}

void Objects::anim2(){
    auto action = Sequence::create(..., CallFunc::create([&](){anim1(); }), NULL);
    object2->runAction(action);
}

Or use CC_CALLBACK_0 instead of CallFunc.

Upvotes: 0

Related Questions