Got end of level working. Added floating coffins, shatter them and collect what comes out.

This commit is contained in:
Storm Dragon
2025-02-01 19:50:13 -05:00
parent 6fda41f57b
commit 0a7052094d
8 changed files with 124 additions and 74 deletions

View File

@@ -7,7 +7,6 @@ from src.enemy import Enemy
from src.object import Object
from src.player import Player
from src.projectile import Projectile
from src.coffin import CoffinObject
from src.powerup import PowerUp
class Level:
@@ -17,10 +16,24 @@ class Level:
self.enemies = []
self.bouncing_items = []
self.projectiles = [] # Track active projectiles
self.player = Player(levelData["player_start"]["x"], levelData["player_start"]["y"])
self.player = Player(levelData["player_start"]["x"], levelData["player_start"]["y"], sounds)
self.edge_warning_channel = None
self.weapon_hit_channel = None
self.leftBoundary = levelData["boundaries"]["left"]
self.rightBoundary = levelData["boundaries"]["right"]
self.levelId = levelData["level_id"]
# Create end of level object at right boundary
endLevel = Object(
self.rightBoundary,
0, # Same y-level as player start
"end_of_level",
isStatic=True,
isCollectible=False,
isHazard=False
)
self.objects.append(endLevel)
# Load objects and enemies from level data
for obj in levelData["objects"]:
# Handle x position or range
@@ -28,7 +41,7 @@ class Level:
xPos = obj["x_range"]
else:
xPos = [obj["x"], obj["x"]] # Single position as range
# Check if this is a catapult
if obj.get("type") == "catapult":
catapult = Catapult(
@@ -40,6 +53,14 @@ class Level:
firingRange=obj.get("range", 20)
)
self.objects.append(catapult)
# Check if this is a coffin
elif obj.get("type") == "coffin":
coffin = CoffinObject(
xPos[0],
obj["y"],
self.sounds
)
self.objects.append(coffin)
# Check if this is an enemy
elif "enemy_type" in obj:
enemy = Enemy(
@@ -66,6 +87,7 @@ class Level:
self.objects.append(gameObject)
def update_audio(self):
"""Update all audio and entity state."""
currentTime = pygame.time.get_ticks()
# Update regular objects and check for zombie spawning
@@ -156,7 +178,7 @@ class Level:
if self.weapon_hit_channel is not None and not self.weapon_hit_channel.get_busy():
self.weapon_hit_channel = None
# Check for coffin hits - only if we have any coffins
# Check for coffin hits
for obj in self.objects:
if hasattr(obj, 'is_broken'): # Check if it's a coffin without using isinstance
if (not obj.is_broken and
@@ -164,25 +186,27 @@ class Level:
obj.xPos <= attackRange[1] and
self.player.isJumping): # Must be jumping to hit floating coffins
if obj.hit(self.player.xPos):
self.bouncing_items.append(obj.dropped_item)
speak(f"{obj.dropped_item.item_type} falls out!")
if obj.hit(self.player.xPos):
self.bouncing_items.append(obj.dropped_item)
speak(f"{obj.dropped_item.item_type} falls out!")
def handle_collisions(self):
"""Handle all collision checks and return True if level is complete."""
# First check if player is dead
if self.player.get_health() <= 0:
return False
# Process object collisions for hazards and collectibles
for obj in self.objects:
if not obj.isActive:
continue
# Handle grave edge warnings
if obj.isHazard:
distance = abs(self.player.xPos - obj.xPos)
# Check if within 1 tile and moving
if distance <= 2 and not self.player.isJumping:
# Only play edge warning if not already playing
if self.edge_warning_channel is None or not self.edge_warning_channel.get_busy():
self.edge_warning_channel = self.sounds['edge'].play()
else:
if self.edge_warning_channel is not None and not self.edge_warning_channel.get_busy():
self.edge_warning_channel = None
@@ -200,7 +224,26 @@ class Level:
self.sounds[obj.soundName].play()
speak("You fell in an open grave!")
self.player.set_health(0)
return False
# Handle boundaries
if self.player.xPos < self.leftBoundary:
self.player.xPos = self.leftBoundary
speak("Start of level!")
# Check for level completion - takes precedence over everything except death
if self.player.get_health() > 0:
for obj in self.objects:
if obj.soundName == "end_of_level":
# Check if player has reached or passed the end marker
if self.player.xPos >= obj.xPos:
# Stop all current sounds and play end level sound
pygame.mixer.stop()
self.sounds["end_of_level"].play()
return True
return False
def handle_projectiles(self, currentTime):
"""Update projectiles and check for collisions"""
for proj in self.projectiles[:]: # Copy list to allow removal