Fixed critical sound timing bug. Finally, after a couple of days of banging my head against this problem and sound getting progressively worse, it's fixed. Turned out the fix was a very simple timing issue for when to play sounds.
This commit is contained in:
35
sound.py
35
sound.py
@@ -120,24 +120,25 @@ class Sound:
|
||||
pygame.event.clear()
|
||||
pygame.mixer.stop()
|
||||
|
||||
# Play the sound
|
||||
channel = self.sounds[soundName].play(-1 if loop else 0)
|
||||
if not channel:
|
||||
return None
|
||||
|
||||
# Apply appropriate volume settings
|
||||
sfx_volume = self.volumeService.get_sfx_volume()
|
||||
|
||||
# Handle positional audio if positions are provided
|
||||
# Handle positional audio if positions are provided - check range BEFORE starting sound
|
||||
if playerPos is not None and objPos is not None:
|
||||
# Calculate stereo panning
|
||||
left_vol, right_vol = self._get_stereo_panning(playerPos, objPos, centerDistance)
|
||||
|
||||
# Don't play if out of range
|
||||
if left_vol == 0 and right_vol == 0:
|
||||
channel.stop()
|
||||
return None
|
||||
|
||||
# Play the sound
|
||||
channel = self.sounds[soundName].play(-1 if loop else 0)
|
||||
if not channel:
|
||||
return None
|
||||
|
||||
# Apply volume settings
|
||||
if playerPos is not None and objPos is not None:
|
||||
# Apply positional volume adjustments
|
||||
channel.set_volume(volume * left_vol * sfx_volume, volume * right_vol * sfx_volume)
|
||||
else:
|
||||
@@ -351,6 +352,10 @@ def _find_matching_sound(soundPattern, sounds):
|
||||
keys = [k for k in sounds.keys() if re.match("^" + soundPattern + ".*", k)]
|
||||
return random.choice(keys) if keys else None
|
||||
|
||||
def get_available_channel():
|
||||
"""Get an available channel for playing sounds."""
|
||||
return pygame.mixer.find_channel()
|
||||
|
||||
# Global functions for backward compatibility
|
||||
def play_bgm(musicFile):
|
||||
"""Play background music with proper volume settings."""
|
||||
@@ -425,20 +430,22 @@ def play_sound(sound_or_name, volume=1.0, loop=False, playerPos=None, objPos=Non
|
||||
|
||||
# Case 4: Sound name with dictionary
|
||||
elif isinstance(sounds, dict) and isinstance(sound_or_name, str) and sound_or_name in sounds:
|
||||
# Apply volume settings
|
||||
sfx_vol = volumeService.get_sfx_volume()
|
||||
|
||||
# Handle positional audio - check range BEFORE starting sound
|
||||
if playerPos is not None and objPos is not None:
|
||||
left_vol, right_vol = _get_stereo_panning(playerPos, objPos, centerDistance)
|
||||
if left_vol == 0 and right_vol == 0:
|
||||
return None # Don't start sound if out of range
|
||||
|
||||
# Play the sound
|
||||
channel = sounds[sound_or_name].play(-1 if loop else 0)
|
||||
if not channel:
|
||||
return None
|
||||
|
||||
# Apply volume settings
|
||||
sfx_vol = volumeService.get_sfx_volume()
|
||||
|
||||
# Handle positional audio
|
||||
if playerPos is not None and objPos is not None:
|
||||
left_vol, right_vol = _get_stereo_panning(playerPos, objPos, centerDistance)
|
||||
if left_vol == 0 and right_vol == 0:
|
||||
channel.stop()
|
||||
return None
|
||||
channel.set_volume(volume * left_vol * sfx_vol, volume * right_vol * sfx_vol)
|
||||
else:
|
||||
channel.set_volume(volume * sfx_vol)
|
||||
|
Reference in New Issue
Block a user