我正在尝试使用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
答案 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];
}