Extra life added, fixed sounds to use the new functions for volume control Other various improvements.
This commit is contained in:
@@ -37,9 +37,7 @@ class Pumpkin:
|
||||
# Calculate volume and pan for splat sound based on final position
|
||||
volume, left, right = calculate_volume_and_pan(playerX, self.x)
|
||||
if volume > 0: # Only play if within audible range
|
||||
channel = sounds["pumpkin_splat"].play()
|
||||
if channel:
|
||||
channel.set_volume(volume * left, volume * right)
|
||||
obj_play(sounds, 'pumpkin_splat', playerX, self.x, loop=False)
|
||||
|
||||
def check_collision(self, player):
|
||||
"""Check if pumpkin hits player"""
|
||||
@@ -78,7 +76,7 @@ class Catapult(Object):
|
||||
self.lastFireTime = currentTime
|
||||
|
||||
# Play launch sound
|
||||
self.sounds['catapult_launch'].play()
|
||||
play_sound(self.sounds['catapult_launch'])
|
||||
|
||||
# Set up pending pumpkin
|
||||
isHigh = random.choice([True, False])
|
||||
|
@@ -21,7 +21,7 @@ class CoffinObject(Object):
|
||||
"""Handle being hit by the player's weapon"""
|
||||
if not self.is_broken:
|
||||
self.is_broken = True
|
||||
self.sounds['coffin_shatter'].play()
|
||||
play_sound(self.sounds['coffin_shatter'])
|
||||
self.level.player.stats.update_stat('Coffins broken', 1)
|
||||
self.level.player.stats.update_stat('Coffins remaining', -1)
|
||||
|
||||
|
38
src/level.py
38
src/level.py
@@ -181,20 +181,23 @@ class Level:
|
||||
|
||||
# Check for item collection
|
||||
if abs(item.xPos - self.player.xPos) < 1 and self.player.isJumping:
|
||||
self.sounds[f'get_{item.soundName}'].play()
|
||||
play_sound(self.sounds[f'get_{item.soundName}'])
|
||||
item.apply_effect(self.player)
|
||||
item.isActive = False
|
||||
self.bouncing_items.remove(item)
|
||||
|
||||
def handle_combat(self, currentTime):
|
||||
"""Handle combat interactions between player and enemies"""
|
||||
attackRange = self.player.get_attack_range(currentTime)
|
||||
if attackRange:
|
||||
# Only get attack range if attack is active
|
||||
if self.player.currentWeapon and self.player.currentWeapon.is_attack_active(currentTime):
|
||||
attackRange = self.player.currentWeapon.get_attack_range(self.player.xPos, self.player.facingRight)
|
||||
|
||||
# Check for enemy hits
|
||||
for enemy in self.enemies:
|
||||
if enemy.isActive and enemy.xPos >= attackRange[0] and enemy.xPos <= attackRange[1]:
|
||||
if self.weapon_hit_channel is None or not self.weapon_hit_channel.get_busy():
|
||||
self.weapon_hit_channel = self.sounds[self.player.currentWeapon.hitSound].play()
|
||||
self.weapon_hit_channel = play_sound(self.sounds[self.player.currentWeapon.hitSound])
|
||||
|
||||
enemy.take_damage(self.player.currentWeapon.damage)
|
||||
else:
|
||||
@@ -230,7 +233,7 @@ class Level:
|
||||
distance = abs(self.player.xPos - obj.xPos)
|
||||
if distance <= 2 and not self.player.isJumping:
|
||||
if self.edge_warning_channel is None or not self.edge_warning_channel.get_busy():
|
||||
self.edge_warning_channel = self.sounds['edge'].play()
|
||||
self.edge_warning_channel = play_sound(self.sounds['edge'])
|
||||
else:
|
||||
if self.edge_warning_channel is not None and not self.edge_warning_channel.get_busy():
|
||||
self.edge_warning_channel = None
|
||||
@@ -239,16 +242,31 @@ class Level:
|
||||
if obj.isCollectible and self.player.isJumping:
|
||||
currentPos = round(self.player.xPos)
|
||||
if currentPos not in obj.collectedPositions:
|
||||
self.sounds[f'get_{obj.soundName}'].play()
|
||||
play_sound(self.sounds[f'get_{obj.soundName}'])
|
||||
obj.collect_at_position(currentPos)
|
||||
self.player.collectedItems.append(obj.soundName)
|
||||
self.player.stats.update_stat('Items collected', 1)
|
||||
if obj.soundName == "coin":
|
||||
self.player._coins += 1
|
||||
self.player.stats.update_stat('Bone dust', 1)
|
||||
if self.player._coins % 5 == 0:
|
||||
# Only heal if below max health
|
||||
if self.player.get_health() < self.player.get_max_health():
|
||||
self.player.set_health(min(
|
||||
self.player.get_health() + 1,
|
||||
self.player.get_max_health()
|
||||
))
|
||||
|
||||
if self.player._coins % 100 == 0:
|
||||
# Extra life
|
||||
speak("Extra life")
|
||||
self.player._coins = 0
|
||||
self.player._lives += 1
|
||||
play_sound(self.sounds['extra_life'])
|
||||
|
||||
elif obj.isHazard and not self.player.isJumping:
|
||||
if not self.player.isInvincible:
|
||||
self.sounds[obj.soundName].play()
|
||||
play_sound(self.sounds[obj.soundName])
|
||||
speak("You fell in an open grave!")
|
||||
self.player.set_health(0)
|
||||
return False
|
||||
@@ -269,7 +287,7 @@ class Level:
|
||||
if self.player.xPos >= obj.xPos:
|
||||
# Stop all current sounds and play end level sound
|
||||
pygame.mixer.stop()
|
||||
self.sounds["end_of_level"].play()
|
||||
play_sound(self.sounds['end_of_level'])
|
||||
return True
|
||||
|
||||
return False
|
||||
@@ -289,9 +307,7 @@ class Level:
|
||||
# Calculate volume and pan for splat sound based on final position
|
||||
volume, left, right = calculate_volume_and_pan(self.player.xPos, proj.x)
|
||||
if volume > 0: # Only play if within audible range
|
||||
channel = self.sounds["pumpkin_splat"].play()
|
||||
if channel:
|
||||
channel.set_volume(volume * left, volume * right)
|
||||
obj_play(self.sounds, 'pumpkin_splat', self.player.xPos, proj.x, loop=False)
|
||||
break
|
||||
|
||||
def throw_projectile(self):
|
||||
@@ -307,4 +323,4 @@ class Level:
|
||||
proj_info['direction']
|
||||
))
|
||||
# Play throw sound
|
||||
self.sounds['throw_jack_o_lantern'].play()
|
||||
play_sound(self.sounds['throw_jack_o_lantern'])
|
||||
|
@@ -39,7 +39,7 @@ class Player:
|
||||
# Power-up states
|
||||
self.isInvincible = False
|
||||
self.invincibilityStartTime = 0
|
||||
self.invincibilityDuration = 5000 # 5 seconds of invincibility
|
||||
self.invincibilityDuration = 10000 # 10 seconds of invincibility
|
||||
|
||||
# Initialize starting weapon (rusty shovel)
|
||||
self.add_weapon(Weapon(
|
||||
|
@@ -44,10 +44,8 @@ class PowerUp(Object):
|
||||
"""Apply the item's effect when collected"""
|
||||
if self.item_type == 'hand_of_glory':
|
||||
player.start_invincibility()
|
||||
speak("Hand of Glory makes you invincible!")
|
||||
elif self.item_type == 'jack_o_lantern':
|
||||
player.add_jack_o_lantern()
|
||||
speak("Gained a Jack-o'-lantern!")
|
||||
|
||||
# Stop movement sound when collected
|
||||
if self.channel:
|
||||
|
@@ -33,7 +33,7 @@ class SkullStorm(Object):
|
||||
inRange = self.xRange[0] <= player.xPos <= self.xRange[1]
|
||||
if inRange and not self.playerInRange:
|
||||
# Player just entered range - play the warning sound
|
||||
self.sounds['skull_storm'].play()
|
||||
play_sound(self.sounds['skull_storm'])
|
||||
self.playerInRange = True
|
||||
elif not inRange and self.playerInRange: # Only speak when actually leaving range
|
||||
# Player just left range
|
||||
@@ -62,7 +62,7 @@ class SkullStorm(Object):
|
||||
skull['x'],
|
||||
self.yPos,
|
||||
currentY,
|
||||
existingChannel=skull['channel']
|
||||
existing_channel=skull['channel']
|
||||
)
|
||||
|
||||
# Check if we should spawn a new skull
|
||||
@@ -100,10 +100,7 @@ class SkullStorm(Object):
|
||||
channel = pygame.mixer.find_channel(True) # Find an available channel
|
||||
if channel:
|
||||
soundObj = self.sounds['skull_lands']
|
||||
channel.play(soundObj, 0) # Play once (0 = no loops)
|
||||
# Apply positional audio
|
||||
volume, left, right = calculate_volume_and_pan(player.xPos, skull['x'])
|
||||
channel.set_volume(volume * left, volume * right)
|
||||
obj_play(self.sounds, 'skull_lands', player.xPos, skull['x'], loop=False)
|
||||
|
||||
# Check if player was hit
|
||||
if abs(player.xPos - skull['x']) < 1: # Within 1 tile
|
||||
|
Reference in New Issue
Block a user