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,15 +241,18 @@ 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.player = None # Reset player for new game
|
self.currentGame = select_game(self.sounds)
|
||||||
self.gameStartTime = pygame.time.get_ticks() # Set game start time here
|
if self.currentGame:
|
||||||
if self.load_level(1):
|
self.player = None # Reset player for new game
|
||||||
self.game_loop()
|
self.gameStartTime = pygame.time.get_ticks()
|
||||||
|
if self.load_level(1):
|
||||||
|
self.game_loop()
|
||||||
elif choice == "learn_sounds":
|
elif choice == "learn_sounds":
|
||||||
choice = learn_sounds(self.sounds)
|
choice = learn_sounds(self.sounds)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user