Question

I'm getting stuck to implement some Cocos2D animations for my Tetris clone(that works perfectly, no logic bugs, i just want to perform some smooth animation when deleting rows).

The current code(no animation) just drops the block position, like this:

   block.position = ccp(block.position.x, block.position.y - kBlockSize);

This happens in a for loop for, classic tetris programming. But when i try to animate, like this:

id move = [CCMoveBy actionWithDuration:0.5f position:(0, -kBlockSize)];
[block runAction:move];

Some blocks just moves down once, even tough the action may be called multiple times for the same block(when breaking more than one row for example)...

Why that happens ? I know it's a little bit confusing, but the point is that i'm doing the same stuff and getting different results...i could post more code to help clarify!

Thanks!

Was it helpful?

Solution

I'm quite sure actions are parallel operations so you could be calling a CCMoveBy action before a previous one is completed. Some alternatives I have used are...

  1. Monitor for when the action completes by using a CCSequence finishing with a CCCallFunc action that sets a flag. Something like...

    id myAction = [[CCSequence runWithActions:[CCMoveBy actionWithDuration:0.5f position:(0, -kBlockSize)], [CCCallFunc actionWithTarget:self selector:@selector(myFunc)], nil]

  2. Roll your own solution using a velocity variable in a tick or update function where you can get a hold of delta time/# of ticks since the last update

Hope some of that helps.

OTHER TIPS

Thank you guys, those answers help me a lot!

I've tried CCSequences before posting here, but without success. The problem was the following:

Inside the CCSequence that deletes a row, i have 2 actions: the first one fades out the entire row of blocks(duration of x seconds), and the second one drops all the blocks above the row(duration of y seconds).

This works fine if ONLY ONE row needs to be deleted, because if there is more than one row, the next CCSequence starts nearly the same time the previous, reading a incorrect position of the blocks above, leading to a incorrect cascade of blocks.

I solved that using a longer CCSequence, that takes a CCCallFuncND as the last argument:

id fadeOutSequence = [CCSequence actions:fadeout, destroyBlocks, notifyFadeFinish, nil];

//inside method specified for notifyFadeFinish:
id dropAbove = [CCSequence actions: dropBlocks, notifyDropFinish, nil];

//inside method specified for notifyDropFinish
//start a new delete sequence, if there is more rows to delete.

Now going to implement gravity mode, thanks again!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top