Skip to main content

Sounds and Music

All audio goes through Flixel.sound, a FlixelAudioManager built on top of miniaudio via the gdx-miniaudio wrapper. The system separates sound effects from music at the API level: play() is for short effects (the underlying sound is cached after the first load), while playMusic() is for background tracks (streamed from disk and not cached).


Playing sound effects

// Play with defaults (full volume, no loop).
Flixel.sound.play("sfx/jump.wav");

// Play at 80% volume.
Flixel.sound.play("sfx/jump.wav", 0.8f);

// Play looping (useful for ambient sounds managed as an SFX slot).
Flixel.sound.play("sfx/rain.wav", 1.0f, true);

Playing music

playMusic() streams the file from disk and stores the active track in Flixel.sound.music. Calling playMusic() again replaces the current track and stops the previous one.

// Play at full volume, not looping.
Flixel.sound.playMusic("music/theme.ogg");

// Play at 60% volume, looping.
Flixel.sound.playMusic("music/theme.ogg", 0.6f, true);

// Control the current track through the music field.
Flixel.sound.music.pause();
Flixel.sound.music.resume();
Flixel.sound.music.stop();

Global volume

setMasterVolume scales all audio output. Use it for a master volume slider in your settings menu:

// Set to 50%.
Flixel.sound.setMasterVolume(0.5f);

// Adjust by a delta (e.g. from a volume slider).
Flixel.sound.changeMasterVolume(0.1f);

float vol = Flixel.sound.getMasterVolume();

To pause and resume all audio at once (for a pause menu), call Flixel.sound.pause() and Flixel.sound.resume().


The FlixelSound handle

Both play() and playMusic() return a FlixelSound handle. Keep a reference to control that specific instance independently of everything else playing:

FlixelSound engine = Flixel.sound.play("sfx/engine.wav", 1.0f, true);

// Adjust mid-flight.
engine.setVolume(0.4f);
engine.setPitch(1.5f); // Higher pitch = faster engine.
engine.setPan(-0.6f); // Pan left (-1.0 = full left, 0 = center, 1.0 = full right).

// Seek to a specific point (in milliseconds).
engine.setTime(500f);

// Stop and clean up when done.
engine.stop();

Completion signal

onComplete fires once when a non-looping sound finishes playing. Attach a listener before the sound reaches the end:

FlixelSound voiceLine = Flixel.sound.play("sfx/intro_line.wav");
voiceLine.onComplete.addOnce(() -> startCutscene());

Auto-destroy

Set autoDestroy = true to have the manager automatically clean up the handle when the sound finishes. This is the right choice for fire-and-forget effects where you do not need the handle afterwards:

Flixel.sound.play("sfx/coin.wav").setAutoDestroy(true);

Fading

fadeIn and fadeOut are shorthand methods on FlixelSound that drive the volume from one level to another using the tween engine internally:

// Fade the music in from silence over 2 seconds.
FlixelSound track = Flixel.sound.playMusic("music/level.ogg", 0f, true);
track.fadeIn(2.0f);

// Fade out to silence over 1.5 seconds.
track.fadeOut(1.5f);

// Fade between two specific volume levels.
track.fadeIn(1.0f, 0.2f, 0.9f); // From 0.2 to 0.9 over 1 second.
track.fadeOut(1.0f, 0.1f); // From current volume to 0.1 over 1 second.

Spatial audio

Call setPosition(x, y) on a FlixelSound to place it at a world coordinate. The manager automatically computes stereo pan and volume attenuation based on the distance from the main camera, making sounds appear to come from a specific location in the world:

// This explosion sound will be louder on the left if the player is to the right.
FlixelSound explosion = Flixel.sound.play("sfx/explosion.wav");
explosion.setPosition(explosionX, explosionY);

Audio effects

FlixelSound exposes a DSP effect chain you can populate with built-in nodes. Effects are applied in insertion order before the output reaches the mixer:

FlixelSound cave = Flixel.sound.play("sfx/footstep.wav", 1.0f, true);

// Reverb: wetAmount 0.0 (dry) to 1.0 (fully wet).
cave.addReverb(0.6f);

// Echo: 0.3s delay, 0.4 decay (each repeat is 40% quieter).
cave.addEcho(0.3f, 0.4f);

// Low-pass filter: muffle everything above 800 Hz (e.g. for sounds through walls).
cave.addLowPassMuffle(800.0);

// Remove all effects later.
cave.clearAudioEffectChain();

Persistent sounds

By default, FlixelSound instances created during a state are destroyed when that state is exited. Call setPersist(true) to keep a sound alive across state switches — useful for music or ambient loops that should continue through a menu transition:

FlixelSound bgm = Flixel.sound.play("ambience/overworld.ogg", 0.8f, true);
bgm.setPersist(true); // Keep playing when the state changes.