Cocos2d 2.0 SimpleAudioEngine在另一个对象中停止声音效果

时间:2014-06-20 16:55:40

标签: ios objective-c cocos2d-iphone sprite simpleaudioengine

我正在尝试使用Cocos2d 2.0中的simpleaudioengine来停止音频效果。

我有以下情况;

农场场景,每天有两个天空层。这些是在场景中的图层内创建的精灵。 我还有其他角色的sprite类(使用Ray Wenderlichs Space Viking代码)。

触摸天空后,我将夜间变为夜晚,反之亦然,我可以使用农场图层中的ALuint ID(PollitosLayer.m)启动和停止夜间蟋蟀声音效果。

触摸太阳精灵(类)有它自己的ALuint参考我可以开始。但我想要的是在触摸Sky Sprite时停止它。

在同一个PollitosLayer.m中触摸简单的NON-CLASS Sky Sprite时,有没有办法引用Sun类的ALUint?

我的代码摘录如下。

#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 个答案:

答案 0 :(得分:0)

为了简单起见,你可以做的一件事就是让农场层拥有两个天空(白天和黑夜),让天空拥有太阳。这样,当您确定触摸的内容时,您可以看到当前天空的重体(例如太阳)是否被触摸。如果是这样,那么停止所有必要的效果并发挥阳光效果。如果天空本身被触摸,那么你可以在改变日/夜循环并继续播放下一组音频效果之前,停止重音体的音频效果(如果没有播放则无效)。例如:

@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

我希望这有帮助。这个例子只是一个快速的例子,它假定了许多东西,并不是要复制和粘贴,但它应该让你知道如何解决你的困境。如果我误解了这个问题,请告诉我。

<强>编辑:

另外我忘了提及,每个对象都有自己的音频文件数组,你可以有方便的方法来启动和停止它们。例如,假设您有一个名为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

答案 1 :(得分:0)

许多非常感谢Allen S.创建单独的SkyLayer并在其中创建属性,然后在父层中引用这些属性,然后使用onEnter工作。我现在可以引用和停止父图层中其他精灵的天空元素的音频。这是我的onEnter代码。

  • (无效)的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];

}