Got end of level working. Added floating coffins, shatter them and collect what comes out.
This commit is contained in:
71
src/level.py
71
src/level.py
@@ -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
|
||||
|
Reference in New Issue
Block a user