During development of my latest game, Robot Saga: Escape, I created a custom class from scratch that is designed to increase efficency. This class, called SoundObject, is used to manage all the sound functions for my other class files. This allowed me to simply call a SoundObject function from the other classes without having to code all the sound functions into every class. My game is based off of Michael James Williams’ avoider game tutorials, and a few of the variables I use are the same as in his examples. Let’s get started!
Here’s what you need to import:
import flash.display.MovieClip;
import flash.events.Event;
import flash.media.SoundChannel;
import flash.media.SoundTransform;
When making a game, it’s good to think about what features your audience will be looking for. I wanted the player to have the choice of muting the music, sound effects, or both. This calls for creating different Sound Channels. I also like to divide my variables into sections so that they’re easy to refer to. Here’s the first section I created:
VARIABLES
public class SoundObject extends MovieClip {
public var msSoundChannel:SoundChannel;
public var mainSong:MainSong;
public var mainSongTransform:SoundTransform = new SoundTransform(.85);
public var pausePosition:int;
public var mmSoundChannel:SoundChannel;
public var menuMusic:MenuMusic;
public var rolloverSound:RolloverSound;
msSoundChannel is the SoundChannel variable I will use to play the in-game song, mainSong. mainSongTransform is used to simply play the song at 85% volume instead of the default 100%. I did this because I didn’t want the song to completely overpower the sound effects. pausePosition is an integer that we’ll use later on to record the song’s position when the game’s music is muted. mmSoundChannel is is the SoundChannel variable I will use to play the menu music.
public var sfxSoundChannel:SoundChannel;
public var shieldOnSound:ShieldOnSound;
public var levelUpSound:LevelUpSound;
sfxSoundChannel is used for the sound effects in my game. I’ve included a couple of the sounds I used in Robot Saga: Escape as examples.
public var isSfxMuted:Boolean;
public var isMusicMuted:Boolean;
These booleans are crucial to the success of this class! Every sound that’s played only gets played if its boolean is set to false. Wherever you include sound in your games, make sure to check if your game is muted before allowing any sound to play.
FUNCTIONS
public function SoundObject()
{
isMusicMuted = false;
isSfxMuted = false;
mainSong = new MainSong();
shieldOnSound = new ShieldOnSound();
levelUpSound = new LevelUpSound();
menuMusic = new MenuMusic();
rolloverSound = new RolloverSound();
}
This is the code from the SoundObject constructor. It is basically just used to instantiate the variables I already declared above. I’m giving my booleans a value of false, which means that, by default, nothing is muted.
public function playSound(string:String)//not the same as unmute
{
if(string == "main song" && isMusicMuted == false)
{
msSoundChannel = mainSong.play(0,0,mainSongTransform);
msSoundChannel.addEventListener(Event.SOUND_COMPLETE, onMainSongFinished, false, 0, true );
}
else if(string == "menu music" && isMusicMuted == false)
{
mmSoundChannel = menuMusic.play();
mmSoundChannel.addEventListener( Event.SOUND_COMPLETE, onMenuMusicFinished, false, 0, true );
}
else if(string == "rolloverSound" && isSfxMuted == false)
{
sfxSoundChannel = rolloverSound.play();
}
}
The playSound function is meant to encompass almost all of the songs you want to play. Instead of creating a custom function for each song, you can just assign a conditional (“if”) statement testing the string that the user inputs as a parameter. As long as you pick easy-to-remember string names, this should replace the hassle of creating (and trying to remember) custom functions for each sound. This code snippet is just an example to use as a template. My actual playSound function involved a lot more sounds!
If you want to loop your song, create an Event Listener like I did for the two above sounds.
Example:
if(DocumentClass.main.soundObject.isSfxMuted == false)
{
soundObjectMainGame.playSound("levelUpSound");
}
public function muteMusic(string:String)
{
isMusicMuted = true;
if(string == "main song")
{
pausePosition = msSoundChannel.position;
msSoundChannel.stop();
}
else if(string == "menu song")
{
mmSoundChannel.stop();
}
}
The muteMusic function applies only to your songs. As I said above, the mmSoundChannel is used solely for these songs. If you want to record the position at which the song was muted, you can use something like the pausePosition integer I created to hold the position of the main song. I didn’t bother with one for main menu, since it’s only a short loop.
Example:
if(menuScreen != null)
{
soundObject.muteMusic("menu song");
}
public function unmuteMusic()
{
isMusicMuted = false;
if(DocumentClass.main.playScreen != null && DocumentClass.main.playScreen.visible == true)
{
msSoundChannel = mainSong.play(pausePosition);
}
if(DocumentClass.main.menuScreen != null)
{
DocumentClass.main.soundObject.playSound("menu music");
}
}
The unmuteMusic function is a bit different than the muteMusic function. It takes no parameters, and it checks to see what screen is currently showing. If it’s the menu screen, it unmutes the menu music. The same applies to the play screen and the main song.
public function stopMenuMusic()
{
mmSoundChannel.stop();
}
This function was made only for the transition from the main menu to the play screen after the user presses “play”. I originally tried using the muteMusic function to stop the menu music on the transition, but it caused a bug, so I recommend creating a “stop” function for music transitions.
public function onMainSongFinished (event:Event):void
{
msSoundChannel = mainSong.play();
msSoundChannel.addEventListener(Event.SOUND_COMPLETE, onMainSongFinished, false, 0, true );
}
public function onMenuMusicFinished( event:Event ):void
{
mmSoundChannel = menuMusic.play();
mmSoundChannel.addEventListener( Event.SOUND_COMPLETE, onMenuMusicFinished, false, 0, true);
}
These functions should be familiar if you followed the avoider game tutorials (link at beginning of post). All these do is loop the music. The functions get called from the event listeners we created in the playSound method. The loop is infinite because, as soon as the song finishes, this method gets called and the song plays again. Since the event listener gets added each time you start the song, the loop will be endless.
That’s it! That’s the end of the SoundObject class. In summary, here’s what you have to do when creating a sound:
1) Add an instance of the sound
2) Instantiate the sound in the constructor (or anywhere you please)
3) Add an “else if” statement to the playSound method.
If you enjoyed this tutorial, please write a quick comment below with some feedback so I’ll know whether I should make more of them. Thank you!
Image may be NSFW.
Clik here to view.
Clik here to view.
