Arcade Game Development Library
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Audio playback capabilities with support for multiple formats, volume control, spatial audio, and sound effect management for creating immersive game experiences with music and sound effects.
Base sound classes for loading, playing, and controlling audio in games.
class Sound:
"""
Audio sound class for loading and playing sound effects and music.
Supports various audio formats including WAV, OGG, and MP3.
"""
def __init__(self, file_path: str, streaming: bool = False):
"""
Create a sound object from an audio file.
Args:
file_path: Path to audio file or resource handle (e.g., ":resources:sounds/...")
streaming: Whether to stream the audio (for large files like music)
"""
# Properties
file_path: str
streaming: bool
def play(self, volume: float = 1.0, pan: float = 0.0, loop: bool = False, speed: float = 1.0) -> object:
"""
Play the sound with specified parameters.
Args:
volume: Volume level (0.0 = silent, 1.0 = full volume, >1.0 = amplified)
pan: Stereo panning (-1.0 = full left, 0.0 = center, 1.0 = full right)
loop: Whether to loop the sound continuously
speed: Playback speed (1.0 = normal, 2.0 = double speed, 0.5 = half speed)
Returns:
Media player object for controlling playback
"""
def stop(self) -> None:
"""Stop all instances of this sound."""
def get_length(self) -> float:
"""
Get the duration of the sound in seconds.
Returns:
Duration in seconds
"""
def get_volume(self) -> float:
"""
Get the current volume level.
Returns:
Volume level (0.0 to 1.0+)
"""
def set_volume(self, volume: float) -> None:
"""
Set the volume level for new playback instances.
Args:
volume: Volume level (0.0 = silent, 1.0 = full volume)
"""Utility functions for loading sounds and managing audio playback.
def load_sound(file_path: str, streaming: bool = False) -> arcade.Sound:
"""
Load a sound file and return a Sound object.
Args:
file_path: Path to audio file or resource handle
streaming: Whether to stream the audio (recommended for music)
Returns:
Sound object ready for playback
"""
def play_sound(sound: arcade.Sound, volume: float = 1.0, pan: float = 0.0,
loop: bool = False, speed: float = 1.0) -> object:
"""
Play a sound with specified parameters.
Args:
sound: Sound object to play
volume: Volume level (0.0 to 1.0+)
pan: Stereo panning (-1.0 to 1.0)
loop: Whether to loop the sound
speed: Playback speed multiplier
Returns:
Media player object for controlling playback
"""
def stop_sound(player: object) -> None:
"""
Stop a specific sound instance.
Args:
player: Media player object returned from play_sound()
"""Advanced audio control functions for managing playback and applying effects.
def set_background_music(sound: arcade.Sound, volume: float = 0.5) -> None:
"""
Set and start playing background music.
Args:
sound: Sound object to use as background music
volume: Music volume level
"""
def stop_background_music() -> None:
"""Stop the currently playing background music."""
def pause_background_music() -> None:
"""Pause the background music (can be resumed)."""
def resume_background_music() -> None:
"""Resume paused background music."""
def get_background_music_volume() -> float:
"""
Get the current background music volume.
Returns:
Volume level (0.0 to 1.0+)
"""
def set_background_music_volume(volume: float) -> None:
"""
Set the background music volume.
Args:
volume: New volume level (0.0 to 1.0+)
"""Functions for creating positional and directional audio effects.
def play_sound_3d(sound: arcade.Sound, listener_position: tuple[float, float],
sound_position: tuple[float, float], max_distance: float = 1000.0,
volume: float = 1.0) -> object:
"""
Play a sound with 3D spatial positioning.
Args:
sound: Sound object to play
listener_position: (x, y) position of the listener
sound_position: (x, y) position of the sound source
max_distance: Maximum audible distance
volume: Base volume level
Returns:
Media player object for controlling playback
"""
def update_sound_3d(player: object, listener_position: tuple[float, float],
sound_position: tuple[float, float], max_distance: float = 1000.0) -> None:
"""
Update the 3D position of a playing sound.
Args:
player: Media player object from play_sound_3d()
listener_position: New listener position
sound_position: New sound source position
max_distance: Maximum audible distance
"""Classes and functions for handling streaming audio, particularly useful for music and large audio files.
class StreamingSound(arcade.Sound):
"""
Specialized sound class for streaming large audio files from disk.
More memory efficient for long audio tracks like background music.
"""
def __init__(self, file_path: str, buffer_size: int = 65536):
"""
Create a streaming sound.
Args:
file_path: Path to audio file
buffer_size: Size of streaming buffer in bytes
"""
buffer_size: int
def preload_streaming(self, seconds: float = 2.0) -> None:
"""
Preload a portion of the streaming audio to reduce latency.
Args:
seconds: Amount of audio to preload in seconds
"""
def create_sound_stream(file_path: str, buffer_size: int = 65536) -> arcade.StreamingSound:
"""
Create a streaming sound object for large audio files.
Args:
file_path: Path to audio file
buffer_size: Streaming buffer size
Returns:
StreamingSound object
"""Information about supported audio formats and codec capabilities.
# Supported audio formats
SUPPORTED_FORMATS: list[str] = [
".wav", # Waveform Audio File Format (uncompressed)
".ogg", # Ogg Vorbis (compressed, open source)
".mp3", # MPEG Audio Layer 3 (compressed)
".flac", # Free Lossless Audio Codec
".aiff", # Audio Interchange File Format
".au", # Sun/Unix audio format
]
def is_audio_format_supported(file_path: str) -> bool:
"""
Check if an audio file format is supported.
Args:
file_path: Path to audio file
Returns:
True if format is supported, False otherwise
"""
def get_audio_info(file_path: str) -> dict:
"""
Get information about an audio file.
Args:
file_path: Path to audio file
Returns:
Dictionary with audio properties (duration, sample_rate, channels, etc.)
"""import arcade
class SoundEffectsGame(arcade.Window):
def __init__(self):
super().__init__(800, 600, "Sound Effects Example")
self.sound_list = {}
self.background_music = None
def setup(self):
# Load sound effects
self.sound_list["jump"] = arcade.load_sound(":resources:sounds/jump1.wav")
self.sound_list["coin"] = arcade.load_sound(":resources:sounds/coin1.wav")
self.sound_list["hit"] = arcade.load_sound(":resources:sounds/hit1.wav")
self.sound_list["explosion"] = arcade.load_sound(":resources:sounds/explosion1.wav")
# Load and start background music
self.background_music = arcade.load_sound(":resources:music/1918.mp3", streaming=True)
arcade.play_sound(self.background_music, volume=0.3, loop=True)
# Create some sprites for interaction
self.player_list = arcade.SpriteList()
self.coin_list = arcade.SpriteList()
# Player sprite
self.player = arcade.Sprite(":resources:images/animated_characters/female_adventurer/femaleAdventurer_idle.png", 0.5)
self.player.center_x = 400
self.player.center_y = 300
self.player_list.append(self.player)
# Create coins
for i in range(5):
coin = arcade.Sprite(":resources:images/items/coinGold.png", 0.3)
coin.center_x = 150 + i * 100
coin.center_y = 200
self.coin_list.append(coin)
def on_draw(self):
self.clear()
self.player_list.draw()
self.coin_list.draw()
# Draw instructions
arcade.draw_text("SPACE = Jump sound", 10, 550, arcade.color.WHITE, 16)
arcade.draw_text("Move player to collect coins", 10, 525, arcade.color.WHITE, 16)
arcade.draw_text("X = Explosion sound", 10, 500, arcade.color.WHITE, 16)
arcade.draw_text("M = Toggle music", 10, 475, arcade.color.WHITE, 16)
def on_update(self, delta_time):
self.player_list.update()
# Check for coin collisions
coins_hit = arcade.check_for_collision_with_list(self.player, self.coin_list)
for coin in coins_hit:
# Play coin sound with slight volume variation
arcade.play_sound(self.sound_list["coin"], volume=0.8 + (0.4 * random.random()))
coin.remove_from_sprite_lists()
def on_key_press(self, key, modifiers):
if key == arcade.key.SPACE:
# Play jump sound
arcade.play_sound(self.sound_list["jump"], volume=0.5)
elif key == arcade.key.X:
# Play explosion with random pan
pan = (random.random() - 0.5) * 2 # Random pan from -1.0 to 1.0
arcade.play_sound(self.sound_list["explosion"], volume=0.7, pan=pan)
elif key == arcade.key.M:
# Toggle background music
if self.background_music_playing:
arcade.stop_sound(self.background_music)
self.background_music_playing = False
else:
arcade.play_sound(self.background_music, volume=0.3, loop=True)
self.background_music_playing = True
# Movement controls
elif key == arcade.key.LEFT:
self.player.change_x = -5
elif key == arcade.key.RIGHT:
self.player.change_x = 5
elif key == arcade.key.UP:
self.player.change_y = 5
elif key == arcade.key.DOWN:
self.player.change_y = -5
def on_key_release(self, key, modifiers):
if key in (arcade.key.LEFT, arcade.key.RIGHT):
self.player.change_x = 0
elif key in (arcade.key.UP, arcade.key.DOWN):
self.player.change_y = 0
def main():
game = SoundEffectsGame()
game.setup()
arcade.run()
if __name__ == "__main__":
main()import arcade
import math
class SpatialAudioGame(arcade.Window):
def __init__(self):
super().__init__(800, 600, "3D Spatial Audio")
self.player_list = arcade.SpriteList()
self.sound_source_list = arcade.SpriteList()
self.ambient_sound = None
self.sound_players = []
def setup(self):
# Create player (listener)
self.player = arcade.Sprite(":resources:images/animated_characters/female_adventurer/femaleAdventurer_idle.png", 0.4)
self.player.center_x = 400
self.player.center_y = 300
self.player_list.append(self.player)
# Create sound sources around the map
self.sound_sources = []
# Campfire sound source
campfire = arcade.Sprite(":resources:images/tiles/torch1.png", 0.5)
campfire.center_x = 200
campfire.center_y = 200
campfire.sound = arcade.load_sound(":resources:sounds/fire.wav")
self.sound_source_list.append(campfire)
self.sound_sources.append(campfire)
# Water sound source
water = arcade.Sprite(":resources:images/tiles/water.png", 0.5)
water.center_x = 600
water.center_y = 400
water.sound = arcade.load_sound(":resources:sounds/water.wav")
self.sound_source_list.append(water)
self.sound_sources.append(water)
# Start playing spatial sounds
self.start_spatial_sounds()
def start_spatial_sounds(self):
"""Start playing all spatial sound sources."""
for source in self.sound_sources:
player = arcade.play_sound_3d(
source.sound,
listener_position=(self.player.center_x, self.player.center_y),
sound_position=(source.center_x, source.center_y),
max_distance=300.0,
volume=0.5
)
source.player = player
self.sound_players.append(player)
def update_spatial_audio(self):
"""Update 3D audio based on player position."""
listener_pos = (self.player.center_x, self.player.center_y)
for source in self.sound_sources:
source_pos = (source.center_x, source.center_y)
# Update 3D position
arcade.update_sound_3d(
source.player,
listener_position=listener_pos,
sound_position=source_pos,
max_distance=300.0
)
def on_draw(self):
self.clear()
# Draw sound source ranges
for source in self.sound_sources:
# Draw audible range circle
arcade.draw_circle_outline(source.center_x, source.center_y, 300, arcade.color.YELLOW, 2)
self.sound_source_list.draw()
self.player_list.draw()
# Draw instructions and info
arcade.draw_text("Move with arrow keys", 10, 570, arcade.color.WHITE, 16)
arcade.draw_text("Listen to spatial audio effects", 10, 545, arcade.color.WHITE, 16)
# Draw distance to nearest sound source
if self.sound_sources:
nearest = min(self.sound_sources,
key=lambda s: arcade.get_distance_between_sprites(self.player, s))
distance = arcade.get_distance_between_sprites(self.player, nearest)
arcade.draw_text(f"Distance to nearest source: {distance:.1f}", 10, 520, arcade.color.WHITE, 16)
def on_update(self, delta_time):
self.player_list.update()
self.update_spatial_audio()
def on_key_press(self, key, modifiers):
if key == arcade.key.LEFT:
self.player.change_x = -5
elif key == arcade.key.RIGHT:
self.player.change_x = 5
elif key == arcade.key.UP:
self.player.change_y = 5
elif key == arcade.key.DOWN:
self.player.change_y = -5
def on_key_release(self, key, modifiers):
if key in (arcade.key.LEFT, arcade.key.RIGHT):
self.player.change_x = 0
elif key in (arcade.key.UP, arcade.key.DOWN):
self.player.change_y = 0
def main():
game = SpatialAudioGame()
game.setup()
arcade.run()
if __name__ == "__main__":
main()import arcade
class MusicPlayerExample(arcade.Window):
def __init__(self):
super().__init__(800, 600, "Music Player")
self.music_list = []
self.current_track = 0
self.current_player = None
self.is_playing = False
self.volume = 0.7
def setup(self):
# Load music tracks
self.music_list = [
arcade.load_sound(":resources:music/1918.mp3", streaming=True),
arcade.load_sound(":resources:music/funkyrobot.mp3", streaming=True),
]
# Start with first track
self.play_current_track()
def play_current_track(self):
"""Start playing the current track."""
if self.current_player:
arcade.stop_sound(self.current_player)
if self.music_list:
music = self.music_list[self.current_track]
self.current_player = arcade.play_sound(music, volume=self.volume, loop=True)
self.is_playing = True
def next_track(self):
"""Switch to the next track."""
if self.music_list:
self.current_track = (self.current_track + 1) % len(self.music_list)
self.play_current_track()
def previous_track(self):
"""Switch to the previous track."""
if self.music_list:
self.current_track = (self.current_track - 1) % len(self.music_list)
self.play_current_track()
def toggle_playback(self):
"""Toggle play/pause."""
if self.is_playing:
arcade.pause_background_music()
self.is_playing = False
else:
arcade.resume_background_music()
self.is_playing = True
def adjust_volume(self, change: float):
"""Adjust the volume up or down."""
self.volume = max(0.0, min(1.0, self.volume + change))
if self.current_player:
arcade.set_background_music_volume(self.volume)
def on_draw(self):
self.clear()
# Draw music player interface
arcade.draw_text("Music Player", 400, 500, arcade.color.WHITE, 36, anchor_x="center")
if self.music_list:
track_name = f"Track {self.current_track + 1}/{len(self.music_list)}"
arcade.draw_text(track_name, 400, 450, arcade.color.WHITE, 24, anchor_x="center")
status = "Playing" if self.is_playing else "Paused"
arcade.draw_text(f"Status: {status}", 400, 400, arcade.color.WHITE, 20, anchor_x="center")
arcade.draw_text(f"Volume: {self.volume:.1f}", 400, 350, arcade.color.WHITE, 20, anchor_x="center")
# Draw controls
controls = [
"SPACE = Play/Pause",
"N = Next Track",
"P = Previous Track",
"+ = Volume Up",
"- = Volume Down"
]
for i, control in enumerate(controls):
arcade.draw_text(control, 400, 280 - i * 30, arcade.color.LIGHT_GRAY, 16, anchor_x="center")
def on_key_press(self, key, modifiers):
if key == arcade.key.SPACE:
self.toggle_playback()
elif key == arcade.key.N:
self.next_track()
elif key == arcade.key.P:
self.previous_track()
elif key == arcade.key.PLUS or key == arcade.key.EQUAL:
self.adjust_volume(0.1)
elif key == arcade.key.MINUS:
self.adjust_volume(-0.1)
def main():
game = MusicPlayerExample()
game.setup()
arcade.run()
if __name__ == "__main__":
main()Install with Tessl CLI
npx tessl i tessl/pypi-arcade