-
Notifications
You must be signed in to change notification settings - Fork 7
Sound System
The Sound System allows you to play background music and sound effects in the game, through the SoundService
.
See the How to Play Sounds section to learn how to play sounds that have already been defined, or read the SoundFile
, BackgroundMusicService
or EffectMusicService
sections to learn more.
Follow the steps below to play either background music or sound effects. These steps assume that the sounds have been defined in the relevant enums.
- Register the
SoundService
in the*Screen
class of whatever screen you're playing the sound (This is done by default in theMainGameScreen
).
ServiceLocator.registerSoundService(new SoundService());
- Load the necessary
SoundFile
s
try {
ServiceLocator.getSoundService().getBackgroundMusicService()
.loadSounds(Arrays.asList(BackgroundSoundFile.values()));
} catch (InvalidSoundFileException e) {
throw new RuntimeException(e);
}
- Play a chosen
BackgroundMusicType
ServiceLocator.getSoundService().getBackgroundMusicService().play(BackgroundMusicType.NORMAL);
- When disposing the screen, also call dispose on the
BackgroundMusicService
to free resources.
ServiceLocator.getSoundService().getBackgroundMusicService().dispose()
- Register the
SoundService
in the*Screen
class of whatever screen you're playing the sound (This is done by default in theMainGameScreen
).
ServiceLocator.registerSoundService(new SoundService());
- Load the necessary
SoundFile
s
// Add effects that are needed
List<SoundFile> effects = new ArrayList();
// Replace TractorHonk with whatever sound effect you wish to play
effects.add(EffectSoundFile.TractorHonk);
try {
ServiceLocator.getSoundService().getEffectsMusicService().loadSounds(effects);
} catch (InvalidSoundFileException e) {
throw new RuntimeException(e);
}
- Play the sound file
try {
ServiceLocator.getSoundService().getEffectsMusicService().play(EffectSoundFile.TractorHonk);
} catch (InvalidSoundFileException e) {
throw new RuntimeException(e);
}
- When disposing the screen, also call dispose on the
EffectsMusicService
to free resources.
ServiceLocator.getSoundService().getEffectsMusicService().dispose()
This is the parent class which encapsulates the BackgroundMusicService
and the EffectsMusicService
. It does not provide any additional functionality of its own. Instead it simplifies access to the two MusicService
s
The SoundService
needs to be added to the ServiceLocator
so that it can be accessed in the game.
ServiceLocator.registerSoundService(new SoundService());
Instantiating the SoundService also instantiates the two MusicService
s.
The SoundFile
interface is the basis upon which the BackgroundSoundFile
and EffectSoundFile
enums are built. It requires classes to provide one function - getFilePath()
which allows the respective MusicService
to load the sound file so that it is playable.
To define a sound that is playable within the game, you need to modify either the BackgroundSoundFile
or EffectSoundFile
enums that implement this interface. Using an enum and this interface allows you to decouple the name of the sound that is being played from the underlying file. Using an enum also improves the development experience, as your IDE will autocomplete SoundFile
names.
BackgroundSoundFile
s have one additional requirement. When defining a new BackgroundSoundFile
enum value, you must also assign it a BackgroundMusicType
which allows playlists/sequences of background music to be played without any additional logic.
The BackgroundMusicService
handles playback for long background music files which are streamed from disk.
A maximum of 10 tracks can be loaded at any given time, with only one track playing.
The play(BackgroundMusicType type)
function allows a collection of tracks of a given type to be played in a randomised order, replicating the effect of shuffling a playlist in a music app. Types can be defined for various in game events, which allows relevant music to be played without any additional logic. This functionality could be updated to a queue based on gameplay needs.
-
play(BackgroundMusicType type)
- Begins playing loaded Music instances of the provided type, randomly cycling through a sequence of tracks defined in the enum.
- Parameters:
-
type
: The type of background music to be played.
-
- Throws:
-
IllegalStateException
: If there are no available Music instances of the given type.
-
-
play(SoundFile sound, boolean looping)
- Plays a given sound file with specified looping behavior.
- Parameters:
-
sound
: An enum value that implements the SoundFile interface. -
looping
: A flag to control if the sound loops.
-
- Returns:
-
long
: 0 (no play ID is returned for background music instances).
-
- Throws:
-
InvalidSoundFileException
: If the sound file is not an instance of BackgroundSoundFile or is unplayable.
-
-
play(SoundFile sound)
- Plays a given sound file without specifying looping (defaults to false).
- Parameters:
-
sound
: An enum value that implements the SoundFile interface.
-
- Returns:
-
long
: 0 (no play ID is returned for background music instances).
-
- Throws:
-
InvalidSoundFileException
: If the sound file is not an instance of BackgroundSoundFile or is unplayable.
-
-
pause(SoundFile sound)
- Pauses a specific track.
- Parameters:
-
sound
: The SoundFile to pause.
-
- Throws:
-
InvalidSoundFileException
: If the given SoundFile is not active.
-
-
pause()
- Pauses whichever track is currently playing.
-
unPause()
- Unpauses current music if it is paused.
-
stop(SoundFile sound)
- Stops playback for a given sound file.
- Parameters:
-
sound
: An enum value that implements the SoundFile interface.
-
- Throws:
-
InvalidSoundFileException
: If the sound file is not playing.
-
-
setMuted(boolean muted)
- Sets the mute status of the background music.
- Parameters:
-
muted
: The boolean state to set.
-
-
isMuted()
- Returns the current mute status.
- Returns:
-
boolean
: The current mute status.
-
-
isPlaying(SoundFile sound)
- Checks if the given sound file is playing.
- Parameters:
-
sound
: An enum value that implements the SoundFile interface.
-
- Returns:
-
boolean
: True if playing, false if not.
-
- Throws:
-
InvalidSoundFileException
: If the sound file is not loaded or not an instance of BackgroundSoundFile.
-
-
loadSounds(List<SoundFile> sounds)
- Loads a list of sound files into memory (up to 10 tracks).
- Parameters:
-
sounds
: A list of SoundFiles to be loaded into memory.
-
- Throws:
-
InvalidSoundFileException
: If the provided list contains non-BackgroundSoundFile instances.
-
-
dispose()
- Disposes of all loaded Music instances and resets internal maps.
The EffectsMusicService
handles playback for short (less than or equal to 5s) sound effects that are played from memory. The implementation provides a convenient interface over the Gdx.Audio.Sound
class and adds some additional management data structures.
All files must ideally be in the WAV format to ensure consistent playback (looping is unstable for other file formats).
There is no limit on the number of sound effects that can be loaded, but loading too many will cause performance issues, so please be judicious.
Unlike the BackgroundMusicService
, multiple EffectSoundFile
s can be played at the same time. Moreover, multiple instances of the same EffectSoundFile
(for example gunshots) can also be played at the same time. These instances are referred to by their long
integer id, which is returned by the play()
function.
Due to the limitations of LibGDX, the progress of sound effects cannot be tracked. So like a gunshot, once the sound effect is played you only have very limited control over it. Looping sound effects can be controlled to some extent, because they are tracked by the EffectsMusicService
's internal data structure.
-
play(SoundFile soundFile, boolean looping)
- Plays a specified sound effect.
-
Parameters:
-
soundFile
: Enum value implementingEffectSoundFile
interface. -
looping
: Boolean flag indicating whether the sound effect should loop.
-
-
Returns:
-
long
: ID of the playing sound instance.
-
-
play(SoundFile sound)
- Overloaded method for playing a non-looping sound effect.
-
Parameters:
-
sound
: Enum value implementingEffectSoundFile
interface.
-
-
Returns:
-
long
: ID of the playing sound instance.
-
-
pause(SoundFile sound)
- Pauses a specified sound effect (equivalent to
stop(sound)
).
- Pauses a specified sound effect (equivalent to
-
stop(SoundFile soundFile)
- Stops all instances of a specified sound effect.
-
Parameters:
-
soundFile
: Enum value implementingEffectSoundFile
interface.
-
-
stop(SoundFile soundFile, long id)
- Stops a specific instance of a sound effect.
-
Parameters:
-
soundFile
: Enum value implementingEffectSoundFile
interface. -
id
: ID of the sound instance to stop.
-
-
setMuted(boolean muted)
- Sets the mute status for sound playback.
-
Parameters:
-
muted
: Boolean flag indicating mute status.
-
-
isMuted()
- Checks if sound playback is muted.
-
Returns:
-
boolean
: Mute status.
-
-
isPlaying(SoundFile sound)
- Checks if any instance of a specified sound effect is currently playing.
-
Parameters:
-
sound
: Enum value implementingEffectSoundFile
interface.
-
-
Returns:
-
boolean
: Playback status.
-
-
isPlaying(SoundFile sound, long id)
- Checks if a specific instance of a sound effect is playing.
-
Parameters:
-
sound
: Enum value implementingEffectSoundFile
interface. -
id
: ID of the sound instance to check.
-
-
Returns:
-
boolean
: Playback status.
-
-
loadSounds(List<SoundFile> sounds)
- Loads sound files into memory for playback.
-
Parameters:
-
sounds
: List of enum values implementingEffectSoundFile
interface.
-
-
dispose()
- Disposes of all loaded sound resources.
The UML diagram for the Sound System shows how the different classes, interfaces and enumerations interact with each other. EffectsMusicService
and BackgroundMusicService
both implement MusicService
, which are both instantiated by SoundService
. Two enumeration files, BackgroundSoundFile
and BackgroundMusicType
are both called within BackgroundMusicService
as well.