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:
@@ -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
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@@ -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)
BIN
sounds/coffin.ogg
(Stored with Git LFS)
Binary file not shown.
BIN
sounds/locked.ogg
(Stored with Git LFS)
Normal file
BIN
sounds/locked.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
56
src/enemy.py
56
src/enemy.py
@@ -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):
|
||||
|
16
src/level.py
16
src/level.py
@@ -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
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user