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];
}