Cocos2d 2.0 SimpleAudioEngine stop sound effect in another object

354 Views Asked by At

I am trying to stop audio effect using simpleaudioengine in Cocos2d 2.0.

I have the following situation;

Farm Scene with two sky layers day/night. These are placed sprites, created within the layer in the scene. I also have sprite classes for other characters (using Ray Wenderlichs Space Viking code) that are placed.

Upon touching the sky I have the day change to night, and vice versa, and I can start and stop the night crickets sound effect using ALuint ID in the Farm Layer (PollitosLayer.m) .

touching the sun sprite (class) has it's own ALuint reference I can start. But what I want is to STOP it when touching the Sky Sprite.

Is there a way to reference the ALuint of the Sun Class when touching the simple NON-CLASS Sky Sprite in the same PollitosLayer.m?

My code excerpts below.

#import "Sun.h"
#import "PollitosLayer.h"


@implementation Sun


@synthesize sunAnim;
@synthesize settingAnim;

-(void) dealloc {


}

-(void)playSunSound {

    sunSound = PLAYSOUNDEFFECT(SUN_SPIN);

}


-(void)changeState:(CharacterStates)newState {


    [self stopAllActions];

    id action = nil;
characterState = newState;

    switch (newState) {
        case kStateGlowing:


            CCLOG(@"Sun->Changing State to glowing");
            [self setDisplayFrame:
             [[CCSpriteFrameCache sharedSpriteFrameCache]
              spriteFrameByName:@"sun_1.png"]];

            action =  [CCSpawn actions:[CCRepeatForever actionWithAction:
                                        [CCAnimate actionWithAnimation:sunAnim]],nil];
           //[self playSunSound];


            break;

        case kStateSetting:
            CCLOG(@"Sun->Changing State to Setting");
            [self setDisplayFrame:
             [[CCSpriteFrameCache sharedSpriteFrameCache]
              spriteFrameByName:@"sun_1.png"]];

            action =   [CCMoveBy actionWithDuration:3.0f
                                           position:CGPointMake(0.0f,-400.0f)];
          [[SimpleAudioEngine sharedEngine] stopEffect:sunSound];



            break;


        default:
            CCLOG(@"Sun -> Unknown CharState %d",
                  characterState);
            break;

    }

    if (action != nil)
        [self runAction:action];

}

#pragma mark -
-(id) init {
    if( (self=[super init]) ) {
        //CGSize screenSize = [[CCDirector sharedDirector] winSize];
                [self initAnimations];

        [[[CCDirector sharedDirector] touchDispatcher]  addTargetedDelegate:self priority:-1 swallowsTouches:YES];

    }
    return self;


}



-(void) cleanup
{
    // Must manually remove this class as touch input receiver!
    [[CCDirector sharedDirector].touchDispatcher removeDelegate:self];

    [super cleanup];
}


#pragma mark -
#pragma mark initAnimations
-(void)initAnimations {


    [self setSunAnim:
     [self loadPlistForAnimationWithName:@"sunAnim"
                            andClassName:NSStringFromClass([self class])]];


}

-(void) update:(ccTime)delta
{



}


-(void) registerWithTouchDispatcher
{
    [[[CCDirector sharedDirector] touchDispatcher]  addTargetedDelegate:self priority:-1 swallowsTouches:YES];
}



-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
    CGPoint touchLocation = [PollitosLayer locationFromTouch:touch];

    // Check if this touch is on the sun's sprite.
    BOOL isTouchHandled = CGRectContainsPoint([self boundingBox], touchLocation);
    if (isTouchHandled)
    {

        [self changeState:kStateGlowing];


        [self runAction:[CCRotateBy actionWithDuration:1.0f angle:360]];

    }

    return isTouchHandled;

}


-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {
    [self playSunSound];

}



@end


farm layer below PollitosLayer.m

#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "Constants.h"
#import "GameManager.h"
#import "PollitosLayer.h"
#import "Pollito.h"
#import "GameObject.h"
#import "Owl.h"
#import "Sun.h"
#import "Chicks.h"
#import "MainScene.h"



@implementation PollitosLayer

@synthesize backbuttonsprite;
@synthesize henNightSprite;
@synthesize henDaySprite;
@synthesize skyDay;
@synthesize skyNight;
@synthesize moon;

ALuint nightcrickets;
ALuint sunSoundLayer;
ALuint sunSound;
ALuint pollitoSound;



+(CGPoint) locationFromTouch:(UITouch*)touch
{
    CGPoint touchLocation = [touch locationInView: [touch view]];
    return [[CCDirector sharedDirector] convertToGL:touchLocation];
}
+(CGPoint) locationFromTouches:(NSSet*)touches
{
    return [self locationFromTouch:[touches anyObject]];
}





-(void)playNightSound {

    nightcrickets = PLAYSOUNDEFFECT(NIGHT_CRICKETS);
}


-(void)playSunSoundLayer {

    sunSoundLayer = PLAYSOUNDEFFECT(SUN_SPIN);
}

-(void)playPollitoSound {

    pollitoSound = PLAYSOUNDEFFECT(POLLITOS_CHIRP);
}




-(id)init {

    self = [super init];
    if (self != nil) {
        CGSize screenSize = [CCDirector sharedDirector].winSize;
        // enable touches
        self.isTouchEnabled = YES;
               srandom(time(NULL)); // Seeds the random number generator

        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
            [[CCSpriteFrameCache sharedSpriteFrameCache]
             addSpriteFramesWithFile:@"sceneatlas1_default.plist"];          // 1
            sceneSpriteBatchNode =
            [CCSpriteBatchNode batchNodeWithFile:@"sceneatlas1_default.png"]; // 2
        } else {
            [[CCSpriteFrameCache sharedSpriteFrameCache]
             addSpriteFramesWithFile:@"sceneatlas1_default.plist"];          // 1
            sceneSpriteBatchNode =
            [CCSpriteBatchNode batchNodeWithFile:@"sceneatlas1_default.png"];// 2
        }

        [self addChild:sceneSpriteBatchNode z:70 tag:100];

        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
            [[CCSpriteFrameCache sharedSpriteFrameCache]
             addSpriteFramesWithFile:@"sunsheet_default.plist"];          // 1
            sunSpriteBatchNode =
            [CCSpriteBatchNode batchNodeWithFile:@"sunsheet_default.png"]; // 2
        } else {
            [[CCSpriteFrameCache sharedSpriteFrameCache]
             addSpriteFramesWithFile:@"sunsheet_default.plist"];          // 1
            sunSpriteBatchNode =
            [CCSpriteBatchNode batchNodeWithFile:@"sunsheet_default.png"];// 2
        }
        [self addChild:sunSpriteBatchNode z:6 tag:101];

        [self createObjectOfType:kSun
         //withHealth:100
                      atLocation:ccp(screenSize.width * 0.18f,
                                     screenSize.height * 0.79f)
                      withZValue:10];

        CCSprite *backgroundImage;
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
            // Indicates game is running on iPad
            backgroundImage =
            [CCSprite spriteWithFile:@"pollitosbackground.png"];
        } else {
            backgroundImage =
            [CCSprite spriteWithFile:@"pollitosbackground.png"];
        }

        [backgroundImage setPosition:ccp(screenSize.width/2.0f,
                                         screenSize.height/2.0f)];
        [self addChild:backgroundImage z:20 tag:69];
    }

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        // Indicates game is running on iPad


        skyDay =
        [CCSprite spriteWithFile:@"SkyDay.png"];
    } else {
        skyDay =
        [CCSprite spriteWithFile:@"SkyDay.png"];
    }
    CGSize screenSize = [CCDirector sharedDirector].winSize;
    [skyDay setPosition:ccp(screenSize.width * 0.5f,
                            screenSize.height* 0.75f)];
    [self addChild:skyDay z:0 tag:59]; //skyDay.visible=YES;




    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        // Indicates game is running on iPad
        skyNight =
        [CCSprite spriteWithFile:@"SkyNight.png"];
    } else {
        skyNight =
        [CCSprite spriteWithFile:@"SkyNight.png"];
    }

    [skyNight setPosition:ccp(screenSize.width * 0.5f,
                              screenSize.height * 0.75f)];
    [self addChild:skyNight z:2 tag:51]; skyNight.visible = NO;



    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        // Indicates game is running on iPad
        moon =
        [CCSprite spriteWithFile:@"Moon.png"];
    } else {
        moon =
        [CCSprite spriteWithFile:@"Moon.png"];
    }

    [moon setPosition:ccp(screenSize.width * 0.87f,
                          screenSize.height * 0.51f)];
    [self addChild:moon z:5 tag:52];



    backbuttonsprite =[CCSprite spriteWithFile:@"back.png"];
    [backbuttonsprite setPosition:ccp(screenSize.width * 0.88f,
                                      screenSize.height * 0.95f)];

    [self addChild:backbuttonsprite z:75 tag:75];



    henDaySprite =[CCSprite spriteWithFile:@"henDay.png"];
    [henDaySprite setPosition:ccp(screenSize.width * 0.70f,
                                  screenSize.height * 0.37f)];

    [self addChild:henDaySprite z:60 tag:60];

    henNightSprite =[CCSprite spriteWithFile:@"henNight.png"];
    [henNightSprite setPosition:ccp(screenSize.width * 0.70f,
                                    screenSize.height * 0.37f)];

    [self addChild:henNightSprite z:61 tag:61];
    henNightSprite.visible = NO;



    [self createObjectOfType:kPollito

                  atLocation:ccp(screenSize.width * 0.378f,
                                 screenSize.height * 0.13f)
                  withZValue:21];


    [self createObjectOfType:kPollito2

                  atLocation:ccp(screenSize.width * 0.578f,
                                 screenSize.height * 0.18f)
                  withZValue:22];
    [self createObjectOfType:kPollito3
                       atLocation:ccp(screenSize.width * 0.450f,
                                 screenSize.height * 0.20f)
                  withZValue:23];


    [self createObjectOfType:kPollito4

                  atLocation:ccp(screenSize.width * 0.3f,
                                 screenSize.height * 0.43f)
                  withZValue:24];


    [self createObjectOfType:kPollito5

                  atLocation:ccp(screenSize.width * 0.10f,
                                 screenSize.height * 0.27f)
                  withZValue:25];

    [self createObjectOfType:kPollito6

                  atLocation:ccp(screenSize.width * 0.25f,
                                 screenSize.height * 0.19f)
                  withZValue:26];

    [self createObjectOfType:kPollito7

                  atLocation:ccp(screenSize.width * 0.77f,
                                 screenSize.height * 0.12f)
                  withZValue:27];
    [self createObjectOfType:kPollito8

                  atLocation:ccp(screenSize.width * 0.17f,
                                 screenSize.height * 0.42f)
                  withZValue:28];

    [self createObjectOfType:kChicks
               atLocation:ccp(screenSize.width * 0.73f,
                                 screenSize.height * 0.25f)
                  withZValue:75];

    [self createObjectOfType:kOwl

                  atLocation:ccp(screenSize.width * 0.897f,
                                 screenSize.height * 0.727f)
                  withZValue:29];




    return self;
}


#pragma mark -
-(void)createObjectOfType:(GameObjectType)objectType

               atLocation:(CGPoint)spawnLocation
               withZValue:(int)ZValue {

    if (objectType ==  kPollito) {
        CCLOG(@"Creating the Pollito1");
        Pollito *pollito = [[[Pollito alloc] init] initWithSpriteFrameName:@"pollito_1.png"];
        [pollito setPosition:spawnLocation];
        [sceneSpriteBatchNode addChild:pollito z:ZValue tag:1];
        [pollito changeState:kStatePecking1];




    } else if (objectType == kPollito2) {
        CCLOG(@"Creating the Pollito2");
        Pollito *pollito2 = [[[Pollito alloc]init ]initWithSpriteFrameName:@"pollito_1.png"];
        [pollito2 setPosition:spawnLocation];
        [sceneSpriteBatchNode addChild:pollito2 z:ZValue tag:2];
        [pollito2 changeState:kStatePecking2];


    }else if (objectType == kPollito3) {
        CCLOG(@"Creating the Pollito3");
        Pollito *pollito3 = [[[Pollito alloc] init ]initWithSpriteFrameName:@"pollito_1.png"];
        [pollito3 setPosition:spawnLocation];
        [sceneSpriteBatchNode addChild:pollito3 z:ZValue tag:3];
        [pollito3 changeState:kStatePecking3];


    }else if (objectType == kPollito4) {
        CCLOG(@"Creating the Pollito4");
        Pollito *pollito4 = [[[Pollito alloc] init  ]initWithSpriteFrameName:@"pollito_1.png"];
        [pollito4 setPosition:spawnLocation];
        [sceneSpriteBatchNode addChild:pollito4 z:ZValue tag:4];
        [pollito4 changeState:kStatePecking4];
        [pollito4 setScale:0.8f];


    }else if (objectType == kPollito5) {
        CCLOG(@"Creating the Pollito5");
        Pollito *pollito5 = [[[Pollito alloc] init ]initWithSpriteFrameName:@"pollito_1.png"];
        [pollito5 setPosition:spawnLocation];
        [sceneSpriteBatchNode addChild:pollito5 z:ZValue tag:5];
        [pollito5 changeState:kStatePecking5];


    }else if (objectType == kPollito6) {
        CCLOG(@"Creating the Pollito6");
        Pollito *pollito6 = [[[Pollito alloc] init] initWithSpriteFrameName:@"pollito_1.png"];
        [pollito6 setPosition:spawnLocation];
        [sceneSpriteBatchNode addChild:pollito6 z:ZValue tag:6];
        [pollito6 changeState:kStatePecking6];


    }else if (objectType == kPollito7) {
        CCLOG(@"Creating the Pollito7");
        Pollito *pollito7 = [[[Pollito alloc] init ]initWithSpriteFrameName:@"pollito_1.png"];
        [pollito7 setPosition:spawnLocation];
        [sceneSpriteBatchNode addChild:pollito7 z:ZValue tag:7];
        [pollito7 changeState:kStatePecking7];


    }else if (objectType == kPollito8) {
        CCLOG(@"Creating the Pollito8");
        Pollito *pollito8 = [[[Pollito alloc] init] initWithSpriteFrameName:@"pollito_1.png"];
        [pollito8 setPosition:spawnLocation];
        [sceneSpriteBatchNode addChild:pollito8 z:ZValue tag:8];
        [pollito8 changeState:kStatePecking8];
        [pollito8 setScale:0.8f];


    }else if (objectType == kOwl) {
        CCLOG(@"Creating the Owl");
        Owl *owl = [[[Owl alloc] init ]initWithSpriteFrameName:@"owl_1.png"];
        [owl setPosition:spawnLocation];
        [sceneSpriteBatchNode addChild:owl z:ZValue tag:9];

        owl.visible = NO;

    }else if (objectType == kChicks) {
        CCLOG(@"Creating the Chicks");
        Chicks *chicks = [[[Chicks alloc] init] initWithSpriteFrameName:@"PollitosSleeping_1.png"];
        [chicks setPosition:spawnLocation];
        [sceneSpriteBatchNode addChild:chicks z:ZValue tag:11];

        chicks.visible = NO;


    }else if (objectType ==  kSun) {
        CCLOG(@"Here comes the Sun");
        CCSprite *sun = [[[Sun alloc] init ]initWithSpriteFrameName:@"sun_1.png"];
        [sun setPosition:spawnLocation];
        [sunSpriteBatchNode addChild:sun z:ZValue tag:12];
                      }
}

-(void) registerWithTouchDispatcher
{
    [[[CCDirector sharedDirector] touchDispatcher]  addTargetedDelegate:self priority:0 swallowsTouches:NO];
}


-(void) dealloc
{
    CCLOG(@"%@:worked %@", NSStringFromSelector(_cmd), self);
}


-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{

    CGSize screenSize = [CCDirector sharedDirector].winSize;


    Chicks *chicks = (Chicks*)[sceneSpriteBatchNode getChildByTag:11];
    Sun *sun = (Sun*)[sunSpriteBatchNode getChildByTag:12];
   Owl *owl = (Owl*)[sceneSpriteBatchNode getChildByTag:9];

    CGPoint touchLocation = [PollitosLayer locationFromTouch:touch];

    // Check if this touch is on the pollito sprite.
   if (CGRectContainsPoint([backbuttonsprite boundingBox], touchLocation))

    {
        STOPSOUNDEFFECT(nightcrickets);
        STOPSOUNDEFFECT(pollitoSound);
        STOPSOUNDEFFECT(sunSound);
        STOPSOUNDEFFECT(sunSoundLayer);




       [[GameManager sharedGameManager] runSceneWithID:kMainScene];



    }


    else if ((CGRectContainsPoint([henDaySprite boundingBox], touchLocation))&&(henNightSprite.visible == NO))


    {
        henDaySprite.visible = NO;
        henNightSprite.visible = YES;
        chicks.visible = YES;
      [chicks changeState:kStateChirping];

    }

    else if ((CGRectContainsPoint([henNightSprite boundingBox], touchLocation))&&(henDaySprite.visible == NO))


    {

        henDaySprite.visible = YES;
        henNightSprite.visible = NO;
       chicks.visible = NO;


    }



   else if ((CGRectContainsPoint([skyDay boundingBox], touchLocation)) && (skyNight.visible == NO))


    {
        skyNight.visible = YES;
       owl.visible = YES;

        CCAction *moveUp = [CCMoveTo actionWithDuration:2.0f
                                               position:CGPointMake(screenSize.width * 0.87f,
                                                                    screenSize.height * 0.91f)];
        [moon runAction:moveUp];
        [[SimpleAudioEngine sharedEngine] stopEffect:sunSoundLayer];
        CCAction *sunDown = [CCMoveTo actionWithDuration:2.0f
                                                position:CGPointMake(screenSize.width * 0.18f,
                                                                     screenSize.height * 0.40f)];
        [sun runAction:sunDown];
        STOPSOUNDEFFECT(sunSound);

        [self playNightSound];
      //[[SimpleAudioEngine sharedEngine] stopEffect:sunSound];
        STOPSOUNDEFFECT(sunSoundLayer);


    }else if (((CGRectContainsPoint([skyNight boundingBox], touchLocation)) &&  (skyNight.visible == YES) )){

        skyNight.visible = NO;
        CCAction *moveAction = [CCMoveTo actionWithDuration:2.0f
                                                   position:CGPointMake(screenSize.width * 0.87f, screenSize.height * 0.57f)];
        [moon runAction:moveAction];
        owl.visible = NO;

        CCAction *sunUp = [CCMoveTo actionWithDuration:2.0f
                                              position:CGPointMake(screenSize.width * 0.18f,
                                                                   screenSize.height * 0.79f)];



        [sun runAction:sunUp];

              STOPSOUNDEFFECT(nightcrickets);


    }


    return YES;
}


-(void) ccTouchMoved:(UITouch *)touches withEvent:(UIEvent *)event{


}

-(void) ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event {

}


-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {


}


@end
2

There are 2 best solutions below

11
Allen S On

To keep it simple, one thing you can do is have the farm layer own the two skies (day and night) and have the day sky own the sun. That way when you are determining what is touched, you can see if the current sky's heavily body (e.g. sun) is touched. If so then stop all necessary effects and play the sun effect. If the sky itself is touched then you can stop the heavily body's audio effect (which would do nothing if one was not playing) before changing the day/night cycle and continuing to play the next set of audio effects. For example:

@intereface FarmLayer()

@property (nonatomic, strong) Sky* day;
@property (nonatomic, strong) Sky* night;
@property (nonatomic, weak) Sky* currentSky;

@end

@implementation FarmLayer

- (void)onEnter
{
    [super onEnter];

    self.day = [...];
    self.night = [...];
    self.currentSky = self.day;

    // Couldn't think of a better name but you get what I mean.
    self.day.skyBody = [Sun ...];

    ...
}


- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    // Pseudo-ish code...

    // if self.currentSky && self.currentSky.skyBody is touched
    //    - Stop all necessary audio effects if playing.
    //    - Play sky body audio.
    // else if self.currentSky is touched
    //    - Stop all necessary audio effects (including self.currentSky.skyBody's audio effect).
    //    - If self.currentSky == self.day then switch to night (and vice versa).
    //    - Play all necessary audio effects for the new sky.
    //    - Make self.currentSky equal to the the new sky.
}

@end

I hope this helped. The example is just a quick one that assumes a lot of stuff and is not meant to be copied and pasted but it should give you an idea on how to go about solving your dilemma. Let me know if I misunderstood the question.

Edited:

Also I forgot to mention, each object can have its own array of audio files and you can have convenience methods to start and stop them. So for example assume you had an array property called audioEffects:

@interface Sky()

@property (nonatomic, strong) NSMutableArray* audioFileNames;
@property (nonatomic, strong) NSMutableArray* audioIds;

@end


@implementation Sky

- (void)addSoundEffectWithFileName:(NSString *)fileName
{
    if (!fileName)
    {
        // Handle error.
        return;
    }

    if (!self.audioFileNames)
    {
        self.audioFileNames = [NSMutableArray array];
    }

    [self.audioFileNames addObject:fileName];

    if (!self.audioIds)
    {
        self.audioIds = [NSMutableArray array];
    }

    [self.audioIds addObject:@0];
}

- (void)playAllAudioEffects
{
    for (int i = 0; i < [self.audioFileNames count]; i++)
    {
        NSString* audioFile = self.audioFileNames[i];
        ALuint audioId = [[SimpleAudioEngine sharedEngine] playEffect:audioFile];

        self.audioIds[i] = [NSNumber numberWithUnsignedInt:audioId];
    }
}

- (void)stopAllAudioEffects
{
    for (int i = 0; i < [self.audioIds count]; i++)
    {
        ALuint audioId = [self.audioIds[i] unsignedIntegerValue];
        [[SimpleAudioEngine sharedEngine] stopEffect:audioId];
    }
}

@end
0
user3760983 On

Many Many thanks to Allen S. The creation of the separate SkyLayer and creating the properties inside of it, then referencing those as properties inside the parent layer and then using your onEnter worked. I can now reference and stop the audio of the sky elements from other sprites in the parent layer Here's my onEnter code.

  • (void)onEnter { [super onEnter];

    CGSize screenSize = [CCDirector sharedDirector].winSize;

    self.skyNight = [CCSprite spriteWithFile:@"SkyNight.png"];

    [_skyNight setPosition:ccp(screenSize.width * 0.5f, screenSize.height * 0.75f)]; [self addChild:_skyNight]; _skyNight.visible=NO;

    self.currentsky = self.skyDay;

    self.skyDay = [CCSprite spriteWithFile:@"SkyDay.png"];

    [_skyDay setPosition:ccp(screenSize.width * 0.5f, screenSize.height* 0.75f)]; [self addChild:_skyDay]; _skyDay.visible=YES;

    self.Sunspin = [CCSprite spriteWithFile:@"sun_1.png"]; [_Sunspin setPosition:ccp(screenSize.width * 0.18f,screenSize.height* 0.85f)]; [self addChild:_Sunspin];

}