Spiderweb obstacles added. Latest libstormgames module update. Level 4 created, needs adjustment, currently way too hard.
This commit is contained in:
161
src/level.py
161
src/level.py
@@ -95,6 +95,27 @@ class Level:
|
||||
item=obj.get("item", "random") # Get item type or default to random
|
||||
)
|
||||
self.objects.append(coffin)
|
||||
# Check if this is a spider web
|
||||
elif obj.get("type") == "spider_web":
|
||||
# Check distance from graves
|
||||
isValidPosition = True
|
||||
for existingObj in self.objects:
|
||||
if (existingObj.soundName == "grave" and
|
||||
not hasattr(existingObj, 'graveItem')):
|
||||
distance = abs(obj["x"] - existingObj.xPos)
|
||||
if distance < 3:
|
||||
isValidPosition = False
|
||||
break
|
||||
|
||||
if isValidPosition:
|
||||
web = Object(
|
||||
obj["x"], # Just pass the single x value
|
||||
obj["y"],
|
||||
"spiderweb",
|
||||
isStatic=True,
|
||||
isCollectible=False,
|
||||
)
|
||||
self.objects.append(web)
|
||||
# Check if this is an enemy
|
||||
elif "enemy_type" in obj:
|
||||
enemy = Enemy(
|
||||
@@ -229,7 +250,21 @@ class Level:
|
||||
|
||||
if obj.hit(self.player.xPos):
|
||||
self.bouncing_items.append(obj.dropped_item)
|
||||
#speak(f"{obj.dropped_item.soundName} falls out!")
|
||||
|
||||
def spawn_spider(self, xPos, yPos):
|
||||
"""Spawn a spider at the given position"""
|
||||
spider = Enemy(
|
||||
[xPos - 5, xPos + 5], # Give spider a patrol range
|
||||
yPos,
|
||||
"spider",
|
||||
self.sounds,
|
||||
self,
|
||||
health=8,
|
||||
damage=8,
|
||||
attack_range=1,
|
||||
speed_multiplier=2.0
|
||||
)
|
||||
self.enemies.append(spider)
|
||||
|
||||
def handle_collisions(self):
|
||||
"""Handle all collision checks and return True if level is complete."""
|
||||
@@ -243,7 +278,7 @@ class Level:
|
||||
continue
|
||||
|
||||
# Handle grave edge warnings
|
||||
if obj.isHazard:
|
||||
if obj.isHazard and obj.soundName != "spiderweb": # Explicitly exclude spiderwebs
|
||||
distance = abs(self.player.xPos - obj.xPos)
|
||||
currentTime = pygame.time.get_ticks()
|
||||
if (distance <= 2 and not self.player.isJumping and not self.player.isInvincible
|
||||
@@ -254,56 +289,80 @@ class Level:
|
||||
play_sound(self.sounds['edge'])
|
||||
self.lastWarningTime = currentTime
|
||||
|
||||
if obj.is_in_range(self.player.xPos):
|
||||
if obj.isCollectible and self.player.isJumping:
|
||||
currentPos = round(self.player.xPos)
|
||||
if currentPos not in obj.collectedPositions:
|
||||
play_sound(self.sounds[f'get_{obj.soundName}'])
|
||||
obj.collect_at_position(currentPos)
|
||||
self.player.collectedItems.append(obj.soundName)
|
||||
if not obj.is_in_range(self.player.xPos):
|
||||
continue
|
||||
|
||||
# Handle collectibles
|
||||
if obj.isCollectible and self.player.isJumping:
|
||||
currentPos = round(self.player.xPos)
|
||||
if currentPos not in obj.collectedPositions:
|
||||
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
|
||||
self.player._coins = 0
|
||||
self.player._lives += 1
|
||||
play_sound(self.sounds['get_extra_life'])
|
||||
continue
|
||||
|
||||
# Handle spiderweb - this should trigger for both walking and jumping if not ducking
|
||||
if obj.soundName == "spiderweb" and not self.player.isDucking:
|
||||
# Create and apply web effect
|
||||
webEffect = PowerUp(
|
||||
obj.xPos,
|
||||
obj.yPos,
|
||||
'spiderweb',
|
||||
self.sounds,
|
||||
0 # No direction needed since it's just for effect
|
||||
)
|
||||
webEffect.level = self # Pass level reference for spider spawning
|
||||
play_sound(self.sounds['hit_spiderweb'])
|
||||
webEffect.apply_effect(self.player)
|
||||
|
||||
# Deactivate web
|
||||
obj.isActive = False
|
||||
obj.channel = obj_stop(obj.channel)
|
||||
continue
|
||||
|
||||
# Handle graves and other hazards
|
||||
if obj.isHazard and not self.player.isJumping:
|
||||
if isinstance(obj, GraveObject):
|
||||
can_collect = obj.collect_grave_item(self.player)
|
||||
|
||||
if can_collect:
|
||||
# Successfully collected item while ducking
|
||||
play_sound(self.sounds[f'get_{obj.graveItem}'])
|
||||
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
|
||||
self.player._coins = 0
|
||||
self.player._lives += 1
|
||||
play_sound(self.sounds['get_extra_life'])
|
||||
|
||||
elif obj.isHazard and not self.player.isJumping:
|
||||
if isinstance(obj, GraveObject):
|
||||
can_collect = obj.collect_grave_item(self.player)
|
||||
|
||||
if can_collect:
|
||||
# Successfully collected item while ducking
|
||||
play_sound(self.sounds[f'get_{obj.graveItem}'])
|
||||
self.player.stats.update_stat('Items collected', 1)
|
||||
# Create PowerUp to handle the item effect
|
||||
item = PowerUp(obj.xPos, obj.yPos, obj.graveItem, self.sounds, 1)
|
||||
item.apply_effect(self.player)
|
||||
# Stop grave's current audio channel
|
||||
if obj.channel:
|
||||
obj_stop(obj.channel)
|
||||
# Remove the grave
|
||||
obj.graveItem = None
|
||||
obj.channel = None
|
||||
obj.isActive = False # Mark the grave as inactive after collection
|
||||
continue
|
||||
elif not self.player.isInvincible:
|
||||
# Kill player for normal graves or non-ducking collision
|
||||
play_sound(self.sounds[obj.soundName])
|
||||
speak("You fell in an open grave! Now, it's yours!")
|
||||
self.player.set_health(0)
|
||||
return False
|
||||
# Create PowerUp to handle the item effect
|
||||
item = PowerUp(obj.xPos, obj.yPos, obj.graveItem, self.sounds, 1)
|
||||
item.apply_effect(self.player)
|
||||
# Stop grave's current audio channel
|
||||
if obj.channel:
|
||||
obj_stop(obj.channel)
|
||||
# Remove the grave
|
||||
obj.graveItem = None
|
||||
obj.channel = None
|
||||
obj.isActive = False # Mark the grave as inactive after collection
|
||||
continue
|
||||
elif not self.player.isInvincible:
|
||||
# Kill player for normal graves or non-ducking collision
|
||||
play_sound(self.sounds[obj.soundName])
|
||||
speak("You fell in an open grave! Now, it's yours!")
|
||||
self.player.set_health(0)
|
||||
return False
|
||||
|
||||
# Handle boundaries
|
||||
if self.player.xPos < self.leftBoundary:
|
||||
|
Reference in New Issue
Block a user