Updates to libstormgames submodule. Updated the game to use the menu improvements. Started work on survival mode.
This commit is contained in:
180
wicked_quest.py
180
wicked_quest.py
@@ -10,6 +10,7 @@ from src.object import Object
|
||||
from src.player import Player
|
||||
from src.game_selection import select_game, get_level_path
|
||||
from src.save_manager import SaveManager
|
||||
from src.survival_generator import SurvivalGenerator
|
||||
|
||||
|
||||
class WickedQuest:
|
||||
@@ -24,6 +25,9 @@ class WickedQuest:
|
||||
self.currentGame = None
|
||||
self.runLock = False # Toggle behavior of the run keys
|
||||
self.saveManager = SaveManager()
|
||||
self.survivalGenerator = None
|
||||
self.survivalWave = 1
|
||||
self.survivalScore = 0
|
||||
|
||||
def load_level(self, levelNumber):
|
||||
"""Load a level from its JSON file."""
|
||||
@@ -87,7 +91,7 @@ class WickedQuest:
|
||||
return errors
|
||||
|
||||
def load_game_menu(self):
|
||||
"""Display load game menu with available saves"""
|
||||
"""Display load game menu with available saves using instruction_menu"""
|
||||
save_files = self.saveManager.get_save_files()
|
||||
|
||||
if not save_files:
|
||||
@@ -101,45 +105,17 @@ class WickedQuest:
|
||||
|
||||
options.append("Cancel")
|
||||
|
||||
# Show menu
|
||||
currentIndex = 0
|
||||
lastSpoken = -1
|
||||
# Use instruction_menu for consistent behavior
|
||||
choice = instruction_menu(self.sounds, "Select a save file to load:", *options)
|
||||
|
||||
messagebox("Select a save file to load:")
|
||||
|
||||
while True:
|
||||
if currentIndex != lastSpoken:
|
||||
speak(options[currentIndex])
|
||||
lastSpoken = currentIndex
|
||||
|
||||
event = pygame.event.wait()
|
||||
if event.type == pygame.KEYDOWN:
|
||||
if event.key == pygame.K_ESCAPE:
|
||||
return None
|
||||
elif event.key in [pygame.K_DOWN, pygame.K_s] and currentIndex < len(options) - 1:
|
||||
currentIndex += 1
|
||||
try:
|
||||
self.sounds['menu-move'].play()
|
||||
except:
|
||||
pass
|
||||
elif event.key in [pygame.K_UP, pygame.K_w] and currentIndex > 0:
|
||||
currentIndex -= 1
|
||||
try:
|
||||
self.sounds['menu-move'].play()
|
||||
except:
|
||||
pass
|
||||
elif event.key == pygame.K_RETURN:
|
||||
try:
|
||||
self.sounds['menu-select'].play()
|
||||
except:
|
||||
pass
|
||||
|
||||
if currentIndex == len(options) - 1: # Cancel
|
||||
return None
|
||||
else:
|
||||
return save_files[currentIndex]
|
||||
|
||||
pygame.event.clear()
|
||||
if choice == "Cancel" or choice is None:
|
||||
return None
|
||||
else:
|
||||
# Find the corresponding save file
|
||||
for save_file in save_files:
|
||||
if save_file['display_name'] == choice:
|
||||
return save_file
|
||||
return None
|
||||
|
||||
def auto_save(self):
|
||||
"""Automatically save the game if player has enough bone dust"""
|
||||
@@ -448,10 +424,15 @@ class WickedQuest:
|
||||
display_text(errorLines)
|
||||
continue
|
||||
if self.currentGame:
|
||||
self.player = None # Reset player for new game
|
||||
self.gameStartTime = pygame.time.get_ticks()
|
||||
if self.load_level(1):
|
||||
self.game_loop()
|
||||
# Ask player to choose game mode
|
||||
mode_choice = game_mode_menu(self.sounds)
|
||||
if mode_choice == "campaign":
|
||||
self.player = None # Reset player for new game
|
||||
self.gameStartTime = pygame.time.get_ticks()
|
||||
if self.load_level(1):
|
||||
self.game_loop()
|
||||
elif mode_choice == "survival":
|
||||
self.start_survival_mode()
|
||||
elif choice == "high_scores":
|
||||
board = Scoreboard()
|
||||
scores = board.get_high_scores()
|
||||
@@ -465,6 +446,119 @@ class WickedQuest:
|
||||
elif choice == "learn_sounds":
|
||||
choice = learn_sounds(self.sounds)
|
||||
|
||||
def start_survival_mode(self):
|
||||
"""Initialize and start survival mode."""
|
||||
self.survivalGenerator = SurvivalGenerator(self.currentGame)
|
||||
self.survivalWave = 1
|
||||
self.survivalScore = 0
|
||||
self.player = Player(0, 0, self.sounds)
|
||||
self.gameStartTime = pygame.time.get_ticks()
|
||||
|
||||
# Generate first survival segment
|
||||
levelData = self.survivalGenerator.generate_survival_level(self.survivalWave, 300)
|
||||
self.currentLevel = Level(levelData, self.sounds, self.player)
|
||||
|
||||
messagebox(f"Survival Mode - Wave {self.survivalWave}! Survive as long as you can!")
|
||||
self.survival_loop()
|
||||
|
||||
def survival_loop(self):
|
||||
"""Main survival mode game loop with endless level generation."""
|
||||
clock = pygame.time.Clock()
|
||||
|
||||
while True:
|
||||
currentTime = pygame.time.get_ticks()
|
||||
pygame.event.pump()
|
||||
|
||||
# Handle events
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.KEYDOWN:
|
||||
if event.key == pygame.K_ESCAPE:
|
||||
messagebox(f"Survival ended! Final score: {self.survivalScore}")
|
||||
return
|
||||
elif event.key in [pygame.K_CAPSLOCK, pygame.K_TAB]:
|
||||
self.runLock = not self.runLock
|
||||
speak("Run lock " + ("enabled." if self.runLock else "disabled."))
|
||||
elif event.key == pygame.K_BACKSPACE:
|
||||
pause_game()
|
||||
elif event.type == pygame.QUIT:
|
||||
exit_game()
|
||||
|
||||
# Update game state (following main game_loop pattern)
|
||||
self.currentLevel.player.update(currentTime)
|
||||
self.handle_input()
|
||||
self.currentLevel.update_audio()
|
||||
|
||||
# Handle combat and projectiles
|
||||
self.currentLevel.handle_combat(currentTime)
|
||||
self.currentLevel.handle_projectiles(currentTime)
|
||||
|
||||
# Handle collisions (including collecting items)
|
||||
self.currentLevel.handle_collisions()
|
||||
|
||||
# Check if player reached end of segment - generate new one
|
||||
if self.player.xPos >= self.currentLevel.rightBoundary - 20:
|
||||
self.advance_survival_wave()
|
||||
|
||||
# Check for death first (following main game loop pattern)
|
||||
if self.currentLevel.player.get_health() <= 0:
|
||||
if self.currentLevel.player.get_lives() <= 0:
|
||||
# Game over - stop all sounds
|
||||
pygame.mixer.stop()
|
||||
messagebox(f"Game Over! Final wave: {self.survivalWave}, Final score: {self.survivalScore}")
|
||||
return
|
||||
else:
|
||||
# Player died but has lives left - respawn
|
||||
pygame.mixer.stop()
|
||||
self.currentLevel.player._health = self.currentLevel.player._maxHealth
|
||||
# Reset player position to beginning of current segment
|
||||
self.player.xPos = 10
|
||||
|
||||
# Update score based on survival time
|
||||
self.survivalScore += 1
|
||||
|
||||
clock.tick(60) # 60 FPS
|
||||
|
||||
def advance_survival_wave(self):
|
||||
"""Generate next wave/segment for survival mode."""
|
||||
self.survivalWave += 1
|
||||
|
||||
# Clear any lingering projectiles/sounds from previous wave
|
||||
if hasattr(self, 'currentLevel') and self.currentLevel:
|
||||
self.currentLevel.projectiles.clear()
|
||||
pygame.mixer.stop() # Stop any ongoing catapult/enemy sounds
|
||||
|
||||
# Generate new segment
|
||||
segmentLength = min(500, 300 + (self.survivalWave * 20)) # Longer segments over time
|
||||
levelData = self.survivalGenerator.generate_survival_level(self.survivalWave, segmentLength)
|
||||
|
||||
# Preserve player position but shift to start of new segment
|
||||
playerX = 10
|
||||
self.player.xPos = playerX
|
||||
|
||||
# Create new level
|
||||
self.currentLevel = Level(levelData, self.sounds, self.player)
|
||||
|
||||
speak(f"Wave {self.survivalWave}! Difficulty increased!")
|
||||
|
||||
|
||||
def game_mode_menu(sounds):
|
||||
"""Display game mode selection menu using instruction_menu.
|
||||
|
||||
Args:
|
||||
sounds (dict): Dictionary of loaded sound effects
|
||||
|
||||
Returns:
|
||||
str: Selected game mode or None if cancelled
|
||||
"""
|
||||
choice = instruction_menu(sounds, "Select game mode:", "Campaign", "Survival Mode")
|
||||
|
||||
if choice == "Campaign":
|
||||
return "campaign"
|
||||
elif choice == "Survival Mode":
|
||||
return "survival"
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
game = WickedQuest()
|
||||
|
Reference in New Issue
Block a user