Make the game more level creator friendly by separating levels into adventures. Menu for choosing which adventure you want.
This commit is contained in:
		
							
								
								
									
										178
									
								
								levels/2.json
									
									
									
									
									
								
							
							
						
						
									
										178
									
								
								levels/2.json
									
									
									
									
									
								
							| @@ -1,178 +0,0 @@ | |||||||
| { |  | ||||||
|     "level_id": 2, |  | ||||||
|     "name": "The Graveyard", |  | ||||||
|     "description": "The mausoleum led to an ancient graveyard. Watch out for falling skulls!", |  | ||||||
|     "player_start": { |  | ||||||
|         "x": 0, |  | ||||||
|         "y": 0 |  | ||||||
|     }, |  | ||||||
|     "objects": [ |  | ||||||
|         { |  | ||||||
|             "x": 5, |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coffin", |  | ||||||
|             "type": "coffin" |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [15, 20], |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coin", |  | ||||||
|             "collectible": true, |  | ||||||
|             "static": true |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [21, 29], |  | ||||||
|             "y": 0, |  | ||||||
|             "enemy_type": "goblin", |  | ||||||
|             "health": 2, |  | ||||||
|             "damage": 2, |  | ||||||
|             "attack_range": 1, |  | ||||||
|             "attack_pattern": { |  | ||||||
|                 "type": "patrol" |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x": 35, |  | ||||||
|             "y": 0, |  | ||||||
|             "hazard": true, |  | ||||||
|             "sound": "grave", |  | ||||||
|             "static": true, |  | ||||||
|             "zombie_spawn_chance": 10 |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [33, 38], |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coin", |  | ||||||
|             "collectible": true, |  | ||||||
|             "static": true |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [45, 60], |  | ||||||
|             "y": 12, |  | ||||||
|             "type": "skull_storm", |  | ||||||
|             "damage": 3, |  | ||||||
|             "maximum_skulls": 2, |  | ||||||
|             "frequency": { |  | ||||||
|                 "min": 3, |  | ||||||
|                 "max": 6 |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x": 55, |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coffin", |  | ||||||
|             "type": "coffin", |  | ||||||
|             "item": "guts" |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [65, 70], |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coin", |  | ||||||
|             "collectible": true, |  | ||||||
|             "static": true |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [71, 79], |  | ||||||
|             "y": 0, |  | ||||||
|             "enemy_type": "goblin", |  | ||||||
|             "health": 2, |  | ||||||
|             "damage": 2, |  | ||||||
|             "attack_range": 1, |  | ||||||
|             "attack_pattern": { |  | ||||||
|                 "type": "patrol" |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x": 85, |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coffin", |  | ||||||
|             "type": "coffin" |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x": 95, |  | ||||||
|             "y": 0, |  | ||||||
|             "hazard": true, |  | ||||||
|             "sound": "grave", |  | ||||||
|             "static": true, |  | ||||||
|             "zombie_spawn_chance": 10 |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [105, 108], |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coin", |  | ||||||
|             "collectible": true, |  | ||||||
|             "static": true |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x": 120, |  | ||||||
|             "y": 0, |  | ||||||
|             "type": "catapult", |  | ||||||
|             "fire_interval": 5000, |  | ||||||
|             "range": 15 |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [130, 165], |  | ||||||
|             "y": 15, |  | ||||||
|             "type": "skull_storm", |  | ||||||
|             "damage": 4, |  | ||||||
|             "maximum_skulls": 3, |  | ||||||
|             "frequency": { |  | ||||||
|                 "min": 2, |  | ||||||
|                 "max": 5 |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [145, 150], |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coin", |  | ||||||
|             "collectible": true, |  | ||||||
|             "static": true |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x": 160, |  | ||||||
|             "y": 0, |  | ||||||
|             "hazard": true, |  | ||||||
|             "sound": "grave", |  | ||||||
|             "static": true, |  | ||||||
|             "zombie_spawn_chance": 10 |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x": 170, |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coffin", |  | ||||||
|             "type": "coffin", |  | ||||||
|             "item": "extra_life" |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [175, 180], |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coin", |  | ||||||
|             "collectible": true, |  | ||||||
|             "static": true |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x": 185, |  | ||||||
|             "y": 0, |  | ||||||
|             "hazard": true, |  | ||||||
|             "sound": "grave", |  | ||||||
|             "static": true, |  | ||||||
|             "zombie_spawn_chance": 10 |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [189, 198], |  | ||||||
|             "y": 0, |  | ||||||
|             "enemy_type": "witch", |  | ||||||
|             "health": 2, |  | ||||||
|             "damage": 2, |  | ||||||
|             "attack_range": 1.5, |  | ||||||
|             "attack_pattern": { |  | ||||||
|                 "type": "patrol" |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     ], |  | ||||||
|     "boundaries": { |  | ||||||
|         "left": 0, |  | ||||||
|         "right": 200 |  | ||||||
|     }, |  | ||||||
|     "footstep_sound": "footstep_tall_grass" |  | ||||||
| } |  | ||||||
							
								
								
									
										252
									
								
								levels/3.json
									
									
									
									
									
								
							
							
						
						
									
										252
									
								
								levels/3.json
									
									
									
									
									
								
							| @@ -1,252 +0,0 @@ | |||||||
| { |  | ||||||
|     "level_id": 3, |  | ||||||
|     "name": "Endless Graves", |  | ||||||
|     "description": "Graves continue in all directions as far as you can see. The dead seem restless.", |  | ||||||
|     "player_start": { |  | ||||||
|         "x": 0, |  | ||||||
|         "y": 0 |  | ||||||
|     }, |  | ||||||
|     "objects": [ |  | ||||||
|         { |  | ||||||
|             "x_range": [1, 4], |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coin", |  | ||||||
|             "collectible": true, |  | ||||||
|             "static": true |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x": 5, |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coffin", |  | ||||||
|             "type": "coffin" |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [6, 10], |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coin", |  | ||||||
|             "collectible": true, |  | ||||||
|             "static": true |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x": 15, |  | ||||||
|             "y": 0, |  | ||||||
|             "hazard": true, |  | ||||||
|             "sound": "grave", |  | ||||||
|             "static": true, |  | ||||||
|             "zombie_spawn_chance": 25 |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [25, 28], |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coin", |  | ||||||
|             "collectible": true, |  | ||||||
|             "static": true |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [21, 31], |  | ||||||
|             "y": 0, |  | ||||||
|             "enemy_type": "goblin", |  | ||||||
|             "health": 3, |  | ||||||
|             "damage": 2, |  | ||||||
|             "attack_range": 1, |  | ||||||
|             "attack_pattern": { |  | ||||||
|                 "type": "patrol" |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [35, 50], |  | ||||||
|             "y": 12, |  | ||||||
|             "type": "skull_storm", |  | ||||||
|             "damage": 3, |  | ||||||
|             "maximum_skulls": 2, |  | ||||||
|             "frequency": { |  | ||||||
|                 "min": 2, |  | ||||||
|                 "max": 5 |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [40, 44], |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coin", |  | ||||||
|             "collectible": true, |  | ||||||
|             "static": true |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x": 55, |  | ||||||
|             "y": 0, |  | ||||||
|             "hazard": true, |  | ||||||
|             "sound": "grave", |  | ||||||
|             "static": true, |  | ||||||
|             "zombie_spawn_chance": 25 |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [60, 70], |  | ||||||
|             "y": 0, |  | ||||||
|             "enemy_type": "goblin", |  | ||||||
|             "health": 3, |  | ||||||
|             "damage": 2, |  | ||||||
|             "attack_range": 1, |  | ||||||
|             "attack_pattern": { |  | ||||||
|                 "type": "patrol" |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [75, 78], |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coin", |  | ||||||
|             "collectible": true, |  | ||||||
|             "static": true |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [71, 81], |  | ||||||
|             "y": 0, |  | ||||||
|             "enemy_type": "goblin", |  | ||||||
|             "health": 3, |  | ||||||
|             "damage": 2, |  | ||||||
|             "attack_range": 1, |  | ||||||
|             "attack_pattern": { |  | ||||||
|                 "type": "patrol" |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x": 85, |  | ||||||
|             "y": 0, |  | ||||||
|             "hazard": true, |  | ||||||
|             "sound": "grave", |  | ||||||
|             "static": true, |  | ||||||
|             "zombie_spawn_chance": 28 |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x": 85, |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coffin", |  | ||||||
|             "type": "coffin" |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [95, 120], |  | ||||||
|             "y": 15, |  | ||||||
|             "type": "skull_storm", |  | ||||||
|             "damage": 3, |  | ||||||
|             "maximum_skulls": 2, |  | ||||||
|             "frequency": { |  | ||||||
|                 "min": 2, |  | ||||||
|                 "max": 4 |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [105, 115], |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coin", |  | ||||||
|             "collectible": true, |  | ||||||
|             "static": true |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [101, 111], |  | ||||||
|             "y": 0, |  | ||||||
|             "enemy_type": "witch", |  | ||||||
|             "health": 6, |  | ||||||
|             "damage": 2, |  | ||||||
|             "attack_range": 1, |  | ||||||
|             "attack_pattern": { |  | ||||||
|                 "type": "patrol" |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x": 125, |  | ||||||
|             "y": 0, |  | ||||||
|             "hazard": true, |  | ||||||
|             "sound": "grave", |  | ||||||
|             "static": true, |  | ||||||
|             "zombie_spawn_chance": 28 |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x": 135, |  | ||||||
|             "y": 0, |  | ||||||
|             "hazard": true, |  | ||||||
|             "sound": "grave", |  | ||||||
|             "static": true, |  | ||||||
|             "zombie_spawn_chance": 30 |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [140, 150], |  | ||||||
|             "y": 0, |  | ||||||
|             "enemy_type": "goblin", |  | ||||||
|             "health": 3, |  | ||||||
|             "damage": 2, |  | ||||||
|             "attack_range": 1, |  | ||||||
|             "attack_pattern": { |  | ||||||
|                 "type": "patrol" |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [155, 158], |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coin", |  | ||||||
|             "collectible": true, |  | ||||||
|             "static": true |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x": 145, |  | ||||||
|             "y": 3, |  | ||||||
|             "item": "hand_of_glory", |  | ||||||
|             "sound": "coffin", |  | ||||||
|             "type": "coffin" |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [146, 166], |  | ||||||
|             "y": 0, |  | ||||||
|             "enemy_type": "ghoul", |  | ||||||
|             "health": 10, |  | ||||||
|             "damage": 3, |  | ||||||
|             "attack_range": 2, |  | ||||||
|             "attack_pattern": { |  | ||||||
|                 "type": "hunter", |  | ||||||
|                 "turn_threshold": 5 |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [165, 190], |  | ||||||
|             "y": 15, |  | ||||||
|             "type": "skull_storm", |  | ||||||
|             "damage": 4, |  | ||||||
|             "maximum_skulls": 3, |  | ||||||
|             "frequency": { |  | ||||||
|                 "min": 2, |  | ||||||
|                 "max": 4 |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x": 175, |  | ||||||
|             "y": 0, |  | ||||||
|             "type": "catapult", |  | ||||||
|             "fire_interval": 4500, |  | ||||||
|             "range": 20 |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [173, 176], |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coin", |  | ||||||
|             "collectible": true, |  | ||||||
|             "static": true |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x": 185, |  | ||||||
|             "y": 3, |  | ||||||
|             "item": "extra_life", |  | ||||||
|             "sound": "coffin", |  | ||||||
|             "type": "coffin" |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|             "x_range": [190, 195], |  | ||||||
|             "y": 3, |  | ||||||
|             "sound": "coin", |  | ||||||
|             "collectible": true, |  | ||||||
|             "static": true |  | ||||||
|         } |  | ||||||
|     ], |  | ||||||
|     "boundaries": { |  | ||||||
|         "left": 0, |  | ||||||
|         "right": 200 |  | ||||||
|     }, |  | ||||||
|     "footstep_sound": "footstep_tall_grass" |  | ||||||
| } |  | ||||||
							
								
								
									
										133
									
								
								src/game_selection.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								src/game_selection.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | |||||||
|  | import os | ||||||
|  | import time | ||||||
|  | import pygame | ||||||
|  | from os.path import isdir, join | ||||||
|  | from libstormgames import speak | ||||||
|  |  | ||||||
|  | def get_available_games(): | ||||||
|  |     """Get list of available game directories in levels folder. | ||||||
|  |      | ||||||
|  |     Returns: | ||||||
|  |         list: List of game directory names | ||||||
|  |     """ | ||||||
|  |     try: | ||||||
|  |         return [d for d in os.listdir("levels") if isdir(join("levels", d))] | ||||||
|  |     except FileNotFoundError: | ||||||
|  |         return [] | ||||||
|  |  | ||||||
|  | def selection_menu(sounds, *options): | ||||||
|  |     """Display level selection menu. | ||||||
|  |      | ||||||
|  |     Args: | ||||||
|  |         sounds (dict): Dictionary of loaded sound effects | ||||||
|  |         *options: Variable number of menu options | ||||||
|  |          | ||||||
|  |     Returns: | ||||||
|  |         str: Selected option or None if cancelled | ||||||
|  |     """ | ||||||
|  |     loop = True | ||||||
|  |     pygame.mixer.stop() | ||||||
|  |     i = 0 | ||||||
|  |     j = -1 | ||||||
|  |      | ||||||
|  |     # Clear any pending events | ||||||
|  |     pygame.event.clear() | ||||||
|  |      | ||||||
|  |     speak("Select an adventure") | ||||||
|  |     time.sleep(1.0) | ||||||
|  |      | ||||||
|  |     while loop: | ||||||
|  |         if i != j: | ||||||
|  |             speak(options[i]) | ||||||
|  |             j = i | ||||||
|  |              | ||||||
|  |         pygame.event.pump() | ||||||
|  |         event = pygame.event.wait() | ||||||
|  |          | ||||||
|  |         if event.type == pygame.KEYDOWN: | ||||||
|  |             if event.key == pygame.K_ESCAPE: | ||||||
|  |                 return None | ||||||
|  |                  | ||||||
|  |             if event.key == pygame.K_DOWN and i < len(options) - 1: | ||||||
|  |                 i = i + 1 | ||||||
|  |                 try: | ||||||
|  |                     sounds['menu-move'].play() | ||||||
|  |                 except: | ||||||
|  |                     pass | ||||||
|  |                      | ||||||
|  |             if event.key == pygame.K_UP and i > 0: | ||||||
|  |                 i = i - 1 | ||||||
|  |                 try: | ||||||
|  |                     sounds['menu-move'].play() | ||||||
|  |                 except: | ||||||
|  |                     pass | ||||||
|  |                      | ||||||
|  |             if event.key == pygame.K_HOME and i != 0: | ||||||
|  |                 i = 0 | ||||||
|  |                 try: | ||||||
|  |                     sounds['menu-move'].play() | ||||||
|  |                 except: | ||||||
|  |                     pass | ||||||
|  |                      | ||||||
|  |             if event.key == pygame.K_END and i != len(options) - 1: | ||||||
|  |                 i = len(options) - 1 | ||||||
|  |                 try: | ||||||
|  |                     sounds['menu-move'].play() | ||||||
|  |                 except: | ||||||
|  |                     pass | ||||||
|  |                      | ||||||
|  |             if event.key == pygame.K_RETURN: | ||||||
|  |                 try: | ||||||
|  |                     sounds['menu-select'].play() | ||||||
|  |                     time.sleep(sounds['menu-select'].get_length()) | ||||||
|  |                 except: | ||||||
|  |                     pass | ||||||
|  |                 return options[i] | ||||||
|  |         elif event.type == pygame.QUIT: | ||||||
|  |             return None | ||||||
|  |              | ||||||
|  |         pygame.event.pump() | ||||||
|  |         event = pygame.event.clear() | ||||||
|  |         time.sleep(0.001) | ||||||
|  |  | ||||||
|  | def select_game(sounds): | ||||||
|  |     """Display game selection menu and return chosen game. | ||||||
|  |      | ||||||
|  |     Args: | ||||||
|  |         sounds (dict): Dictionary of loaded sound effects | ||||||
|  |          | ||||||
|  |     Returns: | ||||||
|  |         str: Selected game directory name or None if cancelled | ||||||
|  |     """ | ||||||
|  |     availableGames = get_available_games() | ||||||
|  |      | ||||||
|  |     if not availableGames: | ||||||
|  |         speak("No games found in levels directory!") | ||||||
|  |         return None | ||||||
|  |          | ||||||
|  |     # Convert directory names to display names (replace underscores with spaces) | ||||||
|  |     menuOptions = [game.replace("_", " ") for game in availableGames] | ||||||
|  |      | ||||||
|  |     choice = selection_menu(sounds, *menuOptions) | ||||||
|  |      | ||||||
|  |     if choice is None: | ||||||
|  |         return None | ||||||
|  |          | ||||||
|  |     # Convert display name back to directory name if needed | ||||||
|  |     gameDir = choice.replace(" ", "_") | ||||||
|  |     if gameDir not in availableGames: | ||||||
|  |         gameDir = choice  # Use original if conversion doesn't match | ||||||
|  |          | ||||||
|  |     return gameDir | ||||||
|  |  | ||||||
|  | def get_level_path(gameDir, levelNum): | ||||||
|  |     """Get full path to level JSON file. | ||||||
|  |      | ||||||
|  |     Args: | ||||||
|  |         gameDir (str): Game directory name | ||||||
|  |         levelNum (int): Level number | ||||||
|  |          | ||||||
|  |     Returns: | ||||||
|  |         str: Full path to level JSON file | ||||||
|  |     """ | ||||||
|  |     return os.path.join("levels", gameDir, f"{levelNum}.json") | ||||||
| @@ -5,6 +5,7 @@ from libstormgames import * | |||||||
| from src.level import Level | from src.level import Level | ||||||
| from src.object import Object | from src.object import Object | ||||||
| from src.player import Player | from src.player import Player | ||||||
|  | from src.game_selection import select_game, get_level_path | ||||||
|  |  | ||||||
|  |  | ||||||
| class WickedQuest: | class WickedQuest: | ||||||
| @@ -15,24 +16,29 @@ class WickedQuest: | |||||||
|         self.gameStartTime = None |         self.gameStartTime = None | ||||||
|         self.lastThrowTime = 0 |         self.lastThrowTime = 0 | ||||||
|         self.throwDelay = 250 |         self.throwDelay = 250 | ||||||
|         self.player = None  # Will be initialized when first level loads |         self.player = None | ||||||
|  |         self.currentGame = None | ||||||
|          |          | ||||||
|     def load_level(self, levelNumber): |     def load_level(self, levelNumber): | ||||||
|         """Load a level from its JSON file.""" |         """Load a level from its JSON file.""" | ||||||
|         levelFile = f"levels/{levelNumber}.json" |         levelFile = get_level_path(self.currentGame, levelNumber) | ||||||
|  |         pygame.event.pump() | ||||||
|         try: |         try: | ||||||
|             with open(levelFile, 'r') as f: |             with open(levelFile, 'r') as f: | ||||||
|                 levelData = json.load(f) |                 levelData = json.load(f) | ||||||
|                  |                  | ||||||
|             # Create player if this is the first level |             # Create player if this is the first level | ||||||
|             if self.player is None: |             if self.player is None: | ||||||
|                 self.player = Player(levelData["player_start"]["x"], levelData["player_start"]["y"], self.sounds) |                 self.player = Player(levelData["player_start"]["x"],  | ||||||
|  |                                    levelData["player_start"]["y"],  | ||||||
|  |                                    self.sounds) | ||||||
|             else: |             else: | ||||||
|                 # Just update player position for new level |                 # Just update player position for new level | ||||||
|                 self.player.xPos = levelData["player_start"]["x"] |                 self.player.xPos = levelData["player_start"]["x"] | ||||||
|                 self.player.yPos = levelData["player_start"]["y"] |                 self.player.yPos = levelData["player_start"]["y"] | ||||||
|                  |                  | ||||||
|             # Pass existing player to new level |             # Pass existing player to new level | ||||||
|  |             pygame.event.pump() | ||||||
|             self.currentLevel = Level(levelData, self.sounds, self.player) |             self.currentLevel = Level(levelData, self.sounds, self.player) | ||||||
|          |          | ||||||
|             # Announce level details |             # Announce level details | ||||||
| @@ -49,6 +55,7 @@ class WickedQuest: | |||||||
|         keys = pygame.key.get_pressed() |         keys = pygame.key.get_pressed() | ||||||
|         player = self.currentLevel.player |         player = self.currentLevel.player | ||||||
|         currentTime = pygame.time.get_ticks() |         currentTime = pygame.time.get_ticks() | ||||||
|  |         pygame.event.pump() | ||||||
|      |      | ||||||
|         # Update running and ducking states |         # Update running and ducking states | ||||||
|         if keys[pygame.K_s] and not player.isDucking: |         if keys[pygame.K_s] and not player.isDucking: | ||||||
| @@ -162,18 +169,19 @@ class WickedQuest: | |||||||
|  |  | ||||||
|         while True: |         while True: | ||||||
|             currentTime = pygame.time.get_ticks() |             currentTime = pygame.time.get_ticks() | ||||||
|  |             pygame.event.pump() | ||||||
|      |      | ||||||
|             # Game volume controls |             # Game volume controls | ||||||
|             for event in pygame.event.get(): |             for event in pygame.event.get(): | ||||||
|                 if event.type == pygame.KEYDOWN: |                 if event.type == pygame.KEYDOWN: | ||||||
|                     # Check for Alt modifier |                     # Check for Alt modifier | ||||||
|                     mods = pygame.key.get_mods() |                     mods = pygame.key.get_mods() | ||||||
|                     alt_pressed = mods & pygame.KMOD_ALT |                     altPressed = mods & pygame.KMOD_ALT | ||||||
|                      |                      | ||||||
|                     if event.key == pygame.K_ESCAPE: |                     if event.key == pygame.K_ESCAPE: | ||||||
|                         return |                         return | ||||||
|                     # Volume controls (require Alt) |                     # Volume controls (require Alt) | ||||||
|                     elif alt_pressed: |                     elif altPressed: | ||||||
|                         if event.key == pygame.K_PAGEUP: |                         if event.key == pygame.K_PAGEUP: | ||||||
|                             adjust_master_volume(0.1) |                             adjust_master_volume(0.1) | ||||||
|                         elif event.key == pygame.K_PAGEDOWN: |                         elif event.key == pygame.K_PAGEDOWN: | ||||||
| @@ -233,13 +241,16 @@ class WickedQuest: | |||||||
|     def run(self): |     def run(self): | ||||||
|         """Main game loop with menu system.""" |         """Main game loop with menu system.""" | ||||||
|         while True: |         while True: | ||||||
|             choice = game_menu(self.sounds, "play", "instructions", "learn_sounds", "credits", "donate", "exit") |             choice = game_menu(self.sounds, "play", "instructions", "learn_sounds",  | ||||||
|  |                              "credits", "donate", "exit") | ||||||
|  |  | ||||||
|             if choice == "exit": |             if choice == "exit": | ||||||
|                 exit_game() |                 exit_game() | ||||||
|             elif choice == "play": |             elif choice == "play": | ||||||
|  |                 self.currentGame = select_game(self.sounds) | ||||||
|  |                 if self.currentGame: | ||||||
|                     self.player = None  # Reset player for new game |                     self.player = None  # Reset player for new game | ||||||
|                 self.gameStartTime = pygame.time.get_ticks()  # Set game start time here |                     self.gameStartTime = pygame.time.get_ticks() | ||||||
|                     if self.load_level(1): |                     if self.load_level(1): | ||||||
|                         self.game_loop() |                         self.game_loop() | ||||||
|             elif choice == "learn_sounds": |             elif choice == "learn_sounds": | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user