Code cleanup, added more functionality. Floating coffins that spawn items, graves can spawn zombies, etc.
This commit is contained in:
92
src/level.py
92
src/level.py
@@ -1,14 +1,20 @@
|
||||
import pygame
|
||||
import random
|
||||
from libstormgames import *
|
||||
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:
|
||||
def __init__(self, levelData, sounds):
|
||||
self.sounds = sounds
|
||||
self.objects = []
|
||||
self.enemies = []
|
||||
self.bouncing_items = []
|
||||
self.projectiles = [] # Track active projectiles
|
||||
self.player = Player(levelData["player_start"]["x"], levelData["player_start"]["y"])
|
||||
|
||||
# Load objects and enemies from level data
|
||||
@@ -39,18 +45,45 @@ class Level:
|
||||
obj["sound"],
|
||||
isStatic=obj.get("static", True),
|
||||
isCollectible=obj.get("collectible", False),
|
||||
isHazard=obj.get("hazard", False)
|
||||
isHazard=obj.get("hazard", False),
|
||||
zombie_spawn_chance=obj.get("zombie_spawn_chance", 0)
|
||||
)
|
||||
self.objects.append(gameObject)
|
||||
|
||||
def update_audio(self):
|
||||
currentTime = pygame.time.get_ticks()
|
||||
|
||||
# Update regular objects
|
||||
# Update regular objects and check for zombie spawning
|
||||
for obj in self.objects:
|
||||
if not obj.isActive:
|
||||
continue
|
||||
|
||||
# Check for potential zombie spawn from graves
|
||||
if (obj.soundName == "grave" and
|
||||
obj.zombie_spawn_chance > 0 and
|
||||
not obj.has_spawned):
|
||||
|
||||
distance = abs(self.player.xPos - obj.xPos)
|
||||
if distance < 6: # Within 6 tiles
|
||||
# Mark as checked before doing anything else to prevent multiple checks
|
||||
obj.has_spawned = True
|
||||
|
||||
roll = random.randint(1, 100)
|
||||
speak(f"Near grave, chance to spawn zombie")
|
||||
if roll <= obj.zombie_spawn_chance:
|
||||
zombie = Enemy(
|
||||
[obj.xPos, obj.xPos],
|
||||
obj.yPos,
|
||||
"zombie",
|
||||
self.sounds,
|
||||
health=3,
|
||||
damage=10,
|
||||
attack_range=1
|
||||
)
|
||||
self.enemies.append(zombie)
|
||||
speak("A zombie emerges from the grave!")
|
||||
|
||||
# Handle object audio
|
||||
if not obj.isStatic:
|
||||
if obj.channel is None or not obj.channel.get_busy():
|
||||
obj.channel = obj_play(self.sounds, obj.soundName, self.player.xPos, obj.xPos)
|
||||
@@ -72,15 +105,43 @@ class Level:
|
||||
enemy.channel = obj_play(self.sounds, enemy.enemyType, self.player.xPos, enemy.xPos)
|
||||
if enemy.channel is not None:
|
||||
enemy.channel = obj_update(enemy.channel, self.player.xPos, enemy.xPos)
|
||||
|
||||
# Update bouncing items
|
||||
for item in self.bouncing_items[:]: # Copy list to allow removal
|
||||
if not item.update(currentTime):
|
||||
self.bouncing_items.remove(item)
|
||||
if not item.isActive:
|
||||
speak(f"{item.soundName} got away!")
|
||||
continue
|
||||
|
||||
# Check for item collection
|
||||
if abs(item.xPos - self.player.xPos) < 1 and self.player.isJumping:
|
||||
self.sounds[f'get_{item.soundName}'].play()
|
||||
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:
|
||||
# Check for enemy hits
|
||||
for enemy in self.enemies:
|
||||
if enemy.isActive and enemy.xPos >= attackRange[0] and enemy.xPos <= attackRange[1]:
|
||||
self.sounds[self.player.currentWeapon.hitSound].play()
|
||||
enemy.take_damage(self.player.currentWeapon.damage)
|
||||
|
||||
# Check for coffin hits - only if we have any coffins
|
||||
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
|
||||
obj.xPos >= attackRange[0] and
|
||||
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!")
|
||||
|
||||
def handle_collisions(self):
|
||||
for obj in self.objects:
|
||||
@@ -99,3 +160,30 @@ class Level:
|
||||
self.sounds[obj.soundName].play()
|
||||
speak("You fell in an open grave!")
|
||||
self.player.set_health(0)
|
||||
|
||||
def handle_projectiles(self, currentTime):
|
||||
"""Update projectiles and check for collisions"""
|
||||
for proj in self.projectiles[:]: # Copy list to allow removal
|
||||
if not proj.update():
|
||||
self.projectiles.remove(proj)
|
||||
continue
|
||||
|
||||
# Check for enemy hits
|
||||
for enemy in self.enemies:
|
||||
if enemy.isActive and abs(proj.x - enemy.xPos) < 1:
|
||||
proj.hit_enemy(enemy)
|
||||
self.projectiles.remove(proj)
|
||||
break
|
||||
|
||||
def throw_projectile(self):
|
||||
"""Have player throw a projectile"""
|
||||
proj_info = self.player.throw_projectile()
|
||||
if proj_info:
|
||||
self.projectiles.append(Projectile(
|
||||
proj_info['type'],
|
||||
proj_info['start_x'],
|
||||
proj_info['direction']
|
||||
))
|
||||
# Play throw sound
|
||||
if f"{proj_info['type']}_throw" in self.sounds:
|
||||
self.sounds[f"{proj_info['type']}_throw"].play()
|
||||
|
Reference in New Issue
Block a user