Hey guys. I want to add a sprite to my main menu that when tapped turns of the audio for the whole app. When it's tapped again, I want the audio to go back. How can I go about doing this? I already have the sprite and 2 pictures for selected and disabled.
Stopping Audio
(11 posts) (4 voices)-
Posted 2 years ago #
-
Here's how to mute it with SimpleAudioEngine:
[[SimpleAudioEngine sharedEngine] setMuted: YES/NO];Posted 2 years ago # -
How do I connect that with my sprite? Can you show me an example please?
Posted 2 years ago # -
You know, like a mute button.
Posted 2 years ago # -
for something like a Mute Button I would use a mode button. basically it is two states On/Off and what they do for on and off is whatever you code them to be. Dad and Geek did a good write up on it. check it out. http://geekanddad.wordpress.com/2010/06/22/enemies-and-combat-how-to-make-a-tile-based-game-with-cocos2d-part-3/
Posted 2 years ago # -
if you read it, there is a section on creating modes so that the character can shoot projectiles.
Posted 2 years ago # -
Oh ok thanks
Posted 2 years ago # -
I always have trouble using modes. I end up with 3 errors when I try using it for a audio on/off toggle. Here's my code.
//init method [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES]; sound = [CCMenuItemImage itemFromNormalImage:@"soundon.png" selectedImage:@"soundon.png" disabledImage:@"soundoff.png" target:self selector:@selector(sound:)]; sound.position = ccp(460, 15); int mode; mode = 0; if (mode == 0) { soundStatus = 1; //warning - Assignment makes pointer from integer without cast [[SimpleAudioEngine sharedEngine] setMuted:YES]; }-(void) spriteCheck:(UITouch *)touchLocation { CGPoint location = [touchLocation locationInView:[touchLocation view]]; location = [[CCDirector sharedDirector] convertToGL:location]; soundRect = CGRectMake((sound.position.x-(sound.contentSize.width)/2), (sound.position.y-(sound.contentSize.height)/2), (sound.contentSize.width), (sound.contentSize.height)); if (CGRectContainsPoint(soundRect, location)) { } } -(void) soundTapped: (id) sender { if (soundStatus.mode == 1) { //warning - Comparison between pointer and integer soundStatus.mode = 0; } else { soundStatus.mode = 1; //warning - Passing argument 1 of setMode makes pointer from integer without a cast } }Posted 2 years ago # -
Hey Joe,
I honestly think for your sake, you should ignore the term 'mode'. This came up a while back when you were trying to create a pause button, and if I remember right, that turned into a confusing mess and the thread got closed...
Think about what you're trying to accomplish. Essentially you want to toggle the sound between two different states, sound on or off. So what type of variable would best handle two different states? Booleans - they can only ever be 0/1, yes/no, on/off, and true/false - nothing in between.
In this case you need to keep track of the sound state not within a single method, but throughout your classes life, right? So for that, you'll need to create a class member. Let's call it _shouldPlaySound - so in your header file:
BOOL _shouldPlaySound;Since you may have objects other than your main layer class wanting to play sounds, it would be helpful if they could check and see if they should be or not - the easiest way to do this is by creating a property. So in your header file again, add this:
@property (nonatomic,readwrite,assign) BOOL shouldPlaySound;I've removed the underscore from the variable's name when creating a property. This is a personal preference but I find it helpful to quickly see if I'm working with a property or directly with the variable at a glance.
So at this point, you can go into your .m file. Since we've created the property, we also need to synthesize the accessors. So under the
@implementation YourClassline, add the following:@synthesize shouldPlaySound = _shouldPlaySound;What this does is generate accessors at compile-time - accessors will allow you to get or set the value of the variable represented by the property, in this case _shouldPlaySound.
self.shouldPlaySound // to get a value self.shouldPlaySound = TRUE // to set a valueor:
[self shouldPlaySound] // to get a value [self setShouldPlaySound:TRUE] // to set a valueSo now we can finally implement some code. You'll want to have a starting value for _shouldPlaySound, and I'm going to assume that by default, yes, you want the sound to play. So in the -init method of your class:
- (id)init... { if ((self = [super init])) { ..... _shouldPlaySound = TRUE; } }So that's a start - now you want to be able to toggle this using your soundTapped: method:
- (void)soundTapped:(id)sender { if (_shouldPlaySound) { _shouldPlaySound = FALSE; } else { _shouldPlaySound = TRUE; } }That's it - tapping your sound button will toggle whether or not your sound should play. But obviously, this is just a useless property unless you actually use it :P
So if you want to determine whether a sound should play from within your main class where we've added this variable, you would do something like the following:
if (_shouldPlaySound) { [[SimpleAudioEngine sharedEngine] playEffect:@"gunshot.aif"]; } // or this would also work if (self.shouldPlaySound) { [[SimpleAudioEngine sharedEngine] playEffect:@"gunshot.aif"]; }So why did we go through the hassle of creating a property, and synthesizing it's accessors if we can just access the _soundShouldPlay directly? Well, that works fine within the class that own's the variable, but what if you have a Character class that plays a sound when the character gets hurt?
// From inside your Character Class -(void)hurtCharacter { if (mainLayerClass.shouldPlaySound) { [[SimpleAudioEngine sharedEngine] playEffect:@"ouch.aif"]; } }There is a bit of a problem here though, and that's what happens when you switch scenes. Your MainLayerClass gets wiped out of memory, and so does your user's choice to mute the sounds or not. So where would be a better place to hold a variable like
_shouldPlaySound? You could move it into your game's AppDelegate, so that any class in your game can access the value by calling:[[UIApplication sharedApplication] delegate].shouldPlaySoundor set it by calling:
[[[UIApplication sharedApplication] delegate] setShouldPlaySound:FALSE];The AppDelegate is a great place for gamewide states like this. Just don't overuse it - ask yourself if it makes sense to put a property there, not just because it's convenient.
Hope that helps. There might be some errors in here, as I'm writing this quickly while I should be working :P
Chris
Posted 2 years ago #
Reply
You must log in to post.