Cocos2d 2.0 SimpleAudioEngine остановить звуковой эффект в другом объекте

Я пытаюсь остановить аудио эффект с помощью simpleaudioengine в Cocos2d 2.0.

У меня следующая ситуация;

Ферма Сцена с двумя слоями неба день / ночь. Это размещенные спрайты, созданные внутри слоя на сцене. У меня также есть спрайт-классы для других персонажей (с использованием кода Ray Wenderlichs Space Viking), которые размещены.

После прикосновения к небу у меня меняется день на ночь, и наоборот, и я могу запускать и останавливать звуковой эффект ночных сверчков, используя ALuint ID на уровне фермы (PollitosLayer.m) .

касание солнечного спрайта (класса) имеет свою собственную ссылку ALuint, которую я могу начать. Но то, что я хочу, это ОСТАНОВИТЬ это, касаясь Небесного Спрайта.

Есть ли способ сослаться на ALuint класса Sun при прикосновении к простому НЕКЛАССНОМУ Небесному Спрайту в том же PollitosLayer.m?

Мой код выдержки ниже.

#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 ответа

Для простоты можно сделать так, чтобы слой фермы владел двумя небесами (днем и ночью), а дневное небо - солнцем. Таким образом, когда вы определяете, к чему прикоснулись, вы можете увидеть, касалось ли тело текущего неба (например, солнца). Если это так, то прекратите все необходимые эффекты и включите эффект солнца. Если коснуться самого неба, то вы можете отключить звуковой эффект тяжелого тела (который ничего бы не сделал, если бы он не играл), прежде чем менять дневной / ночной цикл и продолжать воспроизводить следующий набор звуковых эффектов. Например:

@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

Большое Большое спасибо Аллену С. Создание отдельного SkyLayer и создание свойств внутри него, затем ссылка на них как на свойства внутри родительского слоя и затем использование вашего onEnter сработало. Теперь я могу ссылаться и останавливать звук элементов неба от других спрайтов в родительском слое. Вот мой код onEnter.

  • (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 = ДА;

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

}

Другие вопросы по тегам