Search code examples
cocos2d-iphone

How to check if sprites are hit in special order


I have 3 0f 8 sprites on screen that I would like the reader to hit in order: touching the egges first, then the sugar and finally the lemon (if done correctly a gold cup appears)

  • EggsSprite
  • SugarSprite
  • LemonSprite

the functions I have work but i would like to know if there an easier way to maintain and extend to other sprites onscreen (I have 8 sprites and hope to produce different "recipies")

ccTouchesBegan I detect touches on the sprites

 if(CGRectContainsPoint(EggsSprite.boundingBox, location))
{
    EggsSprite_is_hit = YES;
    NSLog(@"EggsSprite_is_hit = YES");
}

if(CGRectContainsPoint(SugarSprite.boundingBox, location))
{
    SugarSprite_is_hit = YES;
    NSLog(@"RunCheckSugar");
    [self CheckSugar];
}

if(CGRectContainsPoint(LemonSprite.boundingBox, location))
{
      NSLog(@"RunCheckLemon");
    LemonSprite_is_hit = YES;
     [self CheckLemon];
}

this runs

-(void)CheckLemon
{
NSLog(@"LemonSprite is hit");
if(MeringueUnlocked == YES)
   {
     NSLog(@"You made a merangue");
       Award.opacity=255;
   }
else  if(MeringueUnlocked == NO)
{
    NSLog(@"Incorrect order");
     EggsSprite_is_hit = NO;
     LemonSprite_is_hit = NO;
     SugarSprite_is_hit = NO;
    MeringueUnlocked = NO;
}
}

-(void)CheckSugar
{
if(SugarSprite_is_hit == YES && EggsSprite_is_hit== YES)
{
    NSLog(@"SugarSprite is hit");
    NSLog(@"And Egg Sprite is hit");
    SugarSprite_is_hit = NO;
    MeringueUnlocked = YES;
}

else if(SugarSprite_is_hit == YES && EggsSprite_is_hit== YES)
{
    NSLog(@"SugarSprite not hit ressetting all");
    EggsSprite_is_hit = NO;
    LemonSprite_is_hit = NO;
    SugarSprite_is_hit = NO;
    MeringueUnlocked = NO;
}
}

It seems to work ok, but it would be horrible to extend, I cant seem to find any examples on touching sprites in order so any psudo code ideas will be welcome :) as its the approach that Im more stuck on since I'm new to coding.

with thanks :) N


Solution

  • When your sprites are created, assign to their 'tag' properties order in which they should be hit:

    EggsSprite.tag = 1;
    SugarSprite.tag = 2;
    LemonSprite.tag = 3;
    

    Then make an instance variable to store index of last sprite hit:

    int _lastSpriteHitIndex;
    

    and for index of last sprite in your sequence:

    int _finalSpriteIndex;
    

    Set its value somewhere in init (or whatever method you use to create your layer):

    _finalSpriteIndex = 3;
    

    Then in your touch handler:

    // find sprite which was touched
    // compare its tag with tag of last touched sprite
    if (_lastSpriteHitIndex == touchedSprite.tag - 1) 
    {
        // if it is next sprite in our planned order of sprites, 
        // store its tag as _lastSpriteHitIndex
        _lastSpriteHitIndex = touchedSprite.tag;
    
    }
    else
    {
         // if it's wrong sprite, reset sequence
         _lastSpriteHitIndex = 0;
    }
    
    if (_lastSpriteHitIndex == _finalSpriteIndex)
    {
        // Congrats! You hit sprites in correct order! 
    }
    

    Basically it's a finite-state machine in which hitting sprites in correct order advances machine to next state, and hitting wrong sprite resets machine to initial state. _lastSpriteHitIndex repesents current state, _finalSpriteIndex represents final state.

    If you don't want to reset to initial state on wrong sprite hit, just remove else clause - without it machine will simply not advance when hitting wrong sprite.