A couple of small adjustments to level 12 and 13. Added the ability to lock levels meaning all enemies must be defeated before you can pass the right boundary. Raised the volume level of coffins a bit. Fixed hunter style attack patterns.

This commit is contained in:
Storm Dragon
2025-02-11 12:54:48 -05:00
parent 3884ee1ff0
commit 5ca8188c2b
7 changed files with 49 additions and 63 deletions

View File

@@ -1,7 +1,7 @@
{
"level_id": 12,
"name": "Pumpkin Run",
"description": "Angry at the way you just blew through their defenses like that, monsters have decided to man... er monster the catapults. Good luck."
"description": "Angry at the way you just blew through their defenses like that, monsters have decided to man... er monster the catapults. Good luck.",
"player_start": {
"x": 0,
"y": 0
@@ -26,7 +26,7 @@
"y": 0,
"type": "catapult",
"fire_interval": 3000,
"range": 50
"range": 40
},
{
"x_range": [55, 60],
@@ -56,7 +56,7 @@
"y": 0,
"type": "catapult",
"fire_interval": 3000,
"range": 50
"range": 40
},
{
"x_range": [105, 110],
@@ -86,14 +86,14 @@
"y": 0,
"type": "catapult",
"fire_interval": 3000,
"range": 50
"range": 40
},
{
"x_range": [145, 165],
"y": 15,
"type": "skull_storm",
"damage": 4,
"maximum_skulls": 3,
"maximum_skulls": 5,
"frequency": {
"min": 1,
"max": 3
@@ -117,7 +117,7 @@
"y": 0,
"type": "catapult",
"fire_interval": 3000,
"range": 50
"range": 40
},
{
"x_range": [185, 195],
@@ -148,7 +148,7 @@
"y": 0,
"type": "catapult",
"fire_interval": 3000,
"range": 50
"range": 40
},
{
"x_range": [235, 240],
@@ -169,7 +169,7 @@
"y": 0,
"type": "catapult",
"fire_interval": 3000,
"range": 50
"range": 40
},
{
"x_range": [265, 285],
@@ -179,7 +179,7 @@
"maximum_skulls": 3,
"frequency": {
"min": 1,
"max": 3
"max": 5
}
},
{
@@ -194,7 +194,7 @@
"y": 0,
"type": "catapult",
"fire_interval": 3000,
"range": 50
"range": 40
},
{
"x_range": [305, 315],
@@ -220,17 +220,17 @@
"y": 0,
"type": "catapult",
"fire_interval": 3000,
"range": 50
"range": 40
},
{
"x_range": [355, 375],
"y": 15,
"type": "skull_storm",
"damage": 4,
"maximum_skulls": 3,
"maximum_skulls": 5,
"frequency": {
"min": 1,
"max": 3
"max": 5
}
},
{

View File

@@ -2,6 +2,7 @@
"level_id": 13,
"name": "Trick or Treat",
"description": "The end of your journey lies ahead, but the monsters have prepared a special welcome. The air crackles with dark magic, and something massive stirs in the darkness.",
"locked": true,
"player_start": {
"x": 0,
"y": 0

BIN
sounds/coffin.ogg (Stored with Git LFS)

Binary file not shown.

BIN
sounds/locked.ogg (Stored with Git LFS) Normal file

Binary file not shown.

View File

@@ -53,47 +53,11 @@ class Enemy(Object):
return self._currentX
@xPos.setter
def xPos(self, value):
"""Set current x position"""
self._currentX = value
def update_movement(self, player):
"""Update enemy movement based on attack pattern"""
if self.attackPattern['type'] == 'hunter':
# Calculate distance to player
distanceToPlayer = player.xPos - self.xPos
if abs(distanceToPlayer) <= (self.patrolEnd - self.patrolStart): # Use full range
# Player is within movement range
if self.movingRight:
# Moving right
if distanceToPlayer < -self.turnThreshold:
# Player is too far behind us, turn around
self.movingRight = False
else:
self.xPos += self.movementSpeed
else:
# Moving left
if distanceToPlayer > self.turnThreshold:
# Player is too far ahead of us, turn around
self.movingRight = True
else:
self.xPos -= self.movementSpeed
# Ensure we stay within our range
if self.xPos <= self.patrolStart:
self.xPos = self.patrolStart
self.movingRight = True
elif self.xPos >= self.patrolEnd:
self.xPos = self.patrolEnd
self.movingRight = False
else:
# Player out of range, return to normal patrol
self.patrol_movement()
else:
# Default patrol behavior
self.patrol_movement()
def patrol_movement(self):
"""Standard back-and-forth patrol movement"""
if self.movingRight:
@@ -110,18 +74,26 @@ class Enemy(Object):
if not self.isActive or self.health <= 0:
return
# Handle movement based on enemy type
if self.enemyType == "zombie":
# Zombies always chase player
# Handle movement based on enemy type and pattern
if self.enemyType == "zombie" or self.attackPattern['type'] == 'hunter':
# Direct chase behavior for zombies and hunters
if player.xPos > self.xPos:
self.movingRight = True
self.xPos += self.movementSpeed
else:
self.movingRight = False
self.xPos -= self.movementSpeed
# Only enforce level boundaries, not patrol boundaries
if self.xPos < self.level.leftBoundary:
self.xPos = self.level.leftBoundary
self.movingRight = True
elif self.xPos > self.level.rightBoundary:
self.xPos = self.level.rightBoundary
self.movingRight = False
else:
# Other enemies use their attack pattern
self.update_movement(player)
# Other enemies use patrol pattern
self.patrol_movement()
# Check for attack opportunity
if self.can_attack(currentTime, player):

View File

@@ -22,10 +22,11 @@ class Level:
self.player = player
self.lastWarningTime = 0
self.warningInterval = int(self.sounds['edge'].get_length() * 1000) # Convert seconds to milliseconds
self.weapon_hit_channel = None
self.leftBoundary = levelData["boundaries"]["left"]
self.rightBoundary = levelData["boundaries"]["right"]
self.isLocked = levelData.get("locked", False) # Default to False if not specified
self.levelId = levelData["level_id"]
# Get footstep sound for this level, default to 'footstep' if not specified
@@ -143,7 +144,8 @@ class Level:
health=obj.get("health", 5),
damage=obj.get("damage", 1),
attack_range=obj.get("attack_range", 1),
movement_range=obj.get("movement_range", 5)
movement_range=obj.get("movement_range", 5),
attack_pattern=obj.get("attack_pattern", {'type': 'patrol'}) # Add this line
)
self.enemies.append(enemy)
else:
@@ -394,7 +396,15 @@ class Level:
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
# If level is locked, check for remaining enemies
if self.isLocked and any(enemy.isActive for enemy in self.enemies):
speak("You must defeat all enemies before proceeding!")
play_sound(self.sounds['locked'])
# Push player back a bit
self.player.xPos -= 1
return False
# Level complete
pygame.mixer.stop()
play_sound(self.sounds['end_of_level'])
return True

View File

@@ -90,7 +90,7 @@ class WickedQuest:
if keys[pygame.K_c]:
speak(f"{player.get_coins()} gbone dust")
if keys[pygame.K_h]:
speak(f"{player.get_health()} HP")
speak(f"{player.get_health()} health of {player.get_max_health()}")
if keys[pygame.K_l]:
speak(f"{player.get_lives()} lives")
if keys[pygame.K_j]: # Check jack o'lanterns