Reputation: 582
I am writing a blackjack game using cocos2D. Im using CCSequence a lot and in numerous places in my code have issues with it. The problem I'm having is that one action is firing before the previous one is done running. for example:
-(void)standButtonPressed:(id)sender
{
[self removeChildByTag:333];
if ((splitNumber<3)&&(numberSplitHits>0))
{
[self removeChildByTag:333];
splitNumber++;
if ([[hands objectAtIndex:splitNumber]handTotal]==0)
goto end;
[self afterSpliting];
[self addArrow];
return;
}
end:
[self removeChildByTag:333];
[[BackgroundLayer sharedBackground]menuSetup:hand gamePhase:3];
BJDrawnCard *holeCard = [dealerHand getFlippedCard];
[holeCard flipCard];
[[SimpleAudioEngine sharedEngine] playEffect:SND_DEAL_CARD];
[self generateDealerHandDisplay];
[self updateDealerHandScoreDisplay];
id myCallFun1 = [CCCallFunc actionWithTarget:self selector:@selector(finishDrawingDealer)];
id myCallFun2 = [CCCallFunc actionWithTarget:self selector:@selector(checkWhoWonHand)];
id myCallFun3 = [CCCallFuncND actionWithTarget:[BackgroundLayer sharedBackground] selector:@selector(menuSetup:gamePhase:)data:(void*)6];
CCDelayTime *delay = [CCDelayTime actionWithDuration:2];
[self runAction:[CCSequence actions:myCallFun1,delay,myCallFun2,myCallFun3 ,nil]];
}
so myCallFunc2 would start running before myCallFun1 finishes. I have the same problem in other parts of my code when using CCSequence, actions would start in order but not wait for an action to finish before the next one starts.
Is there a better way to sequence actions, or maybe even a substitute to CCSequence?
here is the method that myCallFun1 calls:
-(void)finishDrawingDealer
{
if (dealerHand.handTotal<17)
{
drawnCard=[havila drawFromDeck];
[drawnCard setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache]spriteFrameByName:drawnCard.imageFileName]];
CCMoveTo *move =[self animateDealerCards:drawnCard andPosition:[self dealerCardPosition]];
CCDelayTime *delay = [CCDelayTime
actionWithDuration:0.5];
[dealerHand getCard:drawnCard];
//Run the action
numDealerHits++;
[self performSelector:@selector(updateDealerHandScoreDisplay) withObject:nil afterDelay:1.0];
if (dealerHand.handTotal<17) {
id more = [CCCallFunc actionWithTarget:self selector:@selector(finishDrawingDealer)];
[drawnCard runAction:[CCSequence actions:delay,move,delay,more,nil]];
} else {
[drawnCard runAction:[CCSequence actions:delay,move,delay,nil]];
}
if (dealerHand.handTotal>21)
[self dealerBusted];
}
}
Upvotes: 0
Views: 866
Reputation: 8729
The problem comes from that the CCCallFunc actions are instantaneous. They don't care about how long a given selector takes to run, all they care about is calling that selector. After they have called their selector they have effectively finished their job and then the sequence moves onto the next action.
Instead what you can do is call the next method at the end of each method like follows. I also noticed you wanted a delay which you could do with a sequence and CCCallFunc.
- (void)finishDrawingDealer
{
//Do your work that takes time
//Once it has finished
id callNextMethod = [CCCallFunc actionWithTarget:self selector:@selector(checkWhoWonHand)];
id sequence = [CCSequence actions:[CCDelayTime actionWithDuration:2.0f], callNextMethod, nil];
[self runAction:sequence];
}
Upvotes: 2