mirror of
https://github.com/ApfelTeeSaft/WarioWare-Black-and-WAH.git
synced 2026-08-26 19:33:45 +00:00
213 lines
8.8 KiB
Python
213 lines
8.8 KiB
Python
# game_manager.py
|
|
import pygame
|
|
import json
|
|
import importlib
|
|
import random
|
|
|
|
from engine.scene import Scene
|
|
from engine.menu import Menu
|
|
from engine.transitions import Transition
|
|
from settings import *
|
|
from engine.sound import init_mixer, load_music, play_music, stop_music
|
|
|
|
from engine.prompt_scene import PromptScene
|
|
from engine.result_scene import ResultScene
|
|
|
|
import pygame
|
|
import random
|
|
import json
|
|
from engine.sound import play_music, stop_music, fadeout_music
|
|
from settings import FONT_MD, FONT_LG, WHITE, BLACK, SCREEN_WIDTH, SCREEN_HEIGHT, resource_path
|
|
|
|
# Import all microgame classes
|
|
from microgames.wario.spot_the_bright_one import SpotTheBrightOne
|
|
from microgames.wario.light_it_up import LightItUp
|
|
from microgames.wario.match_the_mood import MatchTheMood
|
|
from microgames.wario.hot_or_cold import HotOrCold
|
|
from microgames.wario.truth_or_lie import TruthOrLie
|
|
|
|
from microgames.ninevolt.insert_cartridge import InsertCartridge
|
|
from microgames.ninevolt.jump_plumber import JumpPlumber
|
|
from microgames.ninevolt.catch_the_disk import CatchTheDisk
|
|
from microgames.ninevolt.pixel_paint import PixelPaint
|
|
from microgames.ninevolt.retro_or_modern import RetroOrModern
|
|
|
|
MICROGAME_CLASSES = {
|
|
'microgames.wario.spot_the_bright_one': SpotTheBrightOne,
|
|
'microgames.wario.light_it_up': LightItUp,
|
|
'microgames.wario.match_the_mood': MatchTheMood,
|
|
'microgames.wario.hot_or_cold': HotOrCold,
|
|
'microgames.wario.truth_or_lie': TruthOrLie,
|
|
'microgames.ninevolt.insert_cartridge': InsertCartridge,
|
|
'microgames.ninevolt.jump_plumber': JumpPlumber,
|
|
'microgames.ninevolt.catch_the_disk': CatchTheDisk,
|
|
'microgames.ninevolt.pixel_paint': PixelPaint,
|
|
'microgames.ninevolt.retro_or_modern': RetroOrModern,
|
|
}
|
|
|
|
class GameManager:
|
|
def __init__(self, screen, game_type=None):
|
|
self.screen = screen
|
|
self.game_type = game_type # 'wario' or 'ninevolt'
|
|
self.current_microgame = None
|
|
self.microgame_start_time = 0
|
|
self.score = 0
|
|
self.lives = 3
|
|
self.game_over = False
|
|
self.speed_level = 0 # 0, 1, 2 for normal, speedup 1, speedup 2
|
|
self.max_speed_levels = 2
|
|
self.initial_microgame_time_limit = 4000 # 4 seconds
|
|
self.current_microgame_time_limit = self.initial_microgame_time_limit
|
|
self.current_music_type = None # Track currently playing music type
|
|
self.load_microgame_list()
|
|
self.load_next_microgame()
|
|
|
|
@property
|
|
def speed(self):
|
|
return 1 + (self.speed_level * 0.2) # Increase speed by 20% per level
|
|
|
|
def load_microgame_list(self):
|
|
with open(resource_path('data/microgame_list.json'), 'r') as f:
|
|
self.microgame_list = json.load(f)
|
|
|
|
def load_next_microgame(self):
|
|
if self.current_microgame:
|
|
# self.current_microgame.unload() # No unload method in Scene class
|
|
pass
|
|
|
|
available_microgames = []
|
|
for module_name in MICROGAME_CLASSES.keys():
|
|
if self.game_type == 'wario' and 'wario' in module_name:
|
|
available_microgames.append(module_name)
|
|
elif self.game_type == 'ninevolt' and 'ninevolt' in module_name:
|
|
available_microgames.append(module_name)
|
|
elif self.game_type is None: # If no specific game_type, allow all
|
|
available_microgames.append(module_name)
|
|
|
|
if not available_microgames:
|
|
print(f"No microgames found for game_type: {self.game_type}. Loading all microgames.")
|
|
available_microgames = list(MICROGAME_CLASSES.keys())
|
|
|
|
microgame_module_name = random.choice(available_microgames)
|
|
MicrogameClass = MICROGAME_CLASSES[microgame_module_name]
|
|
self.current_microgame = MicrogameClass(self)
|
|
self.current_microgame.start()
|
|
self.microgame_start_time = pygame.time.get_ticks()
|
|
# Dynamically set time limit based on microgame's timer and end_timer
|
|
# Add a small buffer (e.g., 500ms) to ensure GameManager doesn't time out prematurely
|
|
self.current_microgame_time_limit = int((self.current_microgame.timer + 0.5) * 1000)
|
|
|
|
# Load and play music based on microgame type
|
|
current_microgame_type = 'wario' if 'wario' in microgame_module_name else 'ninevolt'
|
|
if current_microgame_type != self.current_music_type:
|
|
if current_microgame_type == 'wario':
|
|
load_music(resource_path("Assets/music/wario.ogg"))
|
|
elif current_microgame_type == 'ninevolt':
|
|
load_music(resource_path("Assets/music/9volt.ogg"))
|
|
play_music()
|
|
self.current_music_type = current_microgame_type
|
|
|
|
def update(self, dt):
|
|
if self.game_over:
|
|
return
|
|
|
|
current_time = pygame.time.get_ticks()
|
|
time_left = max(0, self.current_microgame_time_limit - (current_time - self.microgame_start_time))
|
|
self.current_microgame.update(dt, time_left)
|
|
|
|
def draw(self, screen):
|
|
if self.game_over:
|
|
self._draw_game_over()
|
|
else:
|
|
self.current_microgame.draw(self.screen)
|
|
self._draw_ui(screen)
|
|
|
|
def handle_event(self, event):
|
|
if self.game_over:
|
|
return
|
|
self.current_microgame.handle_event(event)
|
|
|
|
def microgame_finished(self, success, game_type=None):
|
|
if self.game_over:
|
|
return
|
|
|
|
if success:
|
|
self.score += 1
|
|
if self.score % 5 == 0 and self.speed_level < self.max_speed_levels:
|
|
self._update_game_speed()
|
|
else:
|
|
self.lives -= 1
|
|
|
|
self._check_game_over()
|
|
if not self.game_over:
|
|
self.current_microgame = ResultScene(self, success, game_type=game_type)
|
|
|
|
def _update_game_speed(self):
|
|
self.speed_level += 1
|
|
# The time limit is recalculated in load_next_microgame
|
|
|
|
def _check_game_over(self):
|
|
if self.lives <= 0:
|
|
self.game_over = True
|
|
fadeout_music(2000) # Fade out music over 2 seconds
|
|
|
|
def _draw_ui(self, screen):
|
|
score_text = FONT_MD.render(f"Score: {self.score}", True, WHITE)
|
|
lives_text = FONT_MD.render(f"Lives: {self.lives}", True, WHITE)
|
|
screen.blit(score_text, (10, 10))
|
|
screen.blit(lives_text, (SCREEN_WIDTH - lives_text.get_width() - 10, 10))
|
|
|
|
# Draw microgame prompt
|
|
if self.current_microgame and hasattr(self.current_microgame, 'prompt'):
|
|
prompt_text = FONT_LG.render(self.current_microgame.prompt, True, WHITE)
|
|
prompt_rect = prompt_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 8))
|
|
screen.blit(prompt_text, prompt_rect)
|
|
|
|
# Draw time bar
|
|
time_left = max(0, self.current_microgame_time_limit - (pygame.time.get_ticks() - self.microgame_start_time))
|
|
bar_width = int((time_left / self.current_microgame_time_limit) * SCREEN_WIDTH)
|
|
pygame.draw.rect(screen, WHITE, (0, SCREEN_HEIGHT - 20, bar_width, 10))
|
|
|
|
def _draw_game_over(self):
|
|
game_over_text = FONT_LG.render("GAME OVER", True, WHITE)
|
|
restart_text = FONT_MD.render("Press R to Restart", True, WHITE)
|
|
self.screen.blit(game_over_text, (SCREEN_WIDTH // 2 - game_over_text.get_width() // 2, SCREEN_HEIGHT // 2 - game_over_text.get_height() // 2))
|
|
self.screen.blit(restart_text, (SCREEN_WIDTH // 2 - restart_text.get_width() // 2, SCREEN_HEIGHT // 2 + restart_text.get_height()))
|
|
|
|
|
|
class GameOverScene(Scene):
|
|
def __init__(self, manager):
|
|
super().__init__(manager)
|
|
|
|
def update(self, dt):
|
|
pass # No continuous update needed for game over screen
|
|
|
|
def handle_event(self, event):
|
|
if event.type == pygame.MOUSEBUTTONDOWN:
|
|
if event.button == 1: # Left click
|
|
stop_music() # Stop music when returning to menu
|
|
self.manager.game_state = "menu"
|
|
self.manager.current_scene = Menu(self.manager)
|
|
elif event.type == pygame.KEYDOWN:
|
|
if event.key == pygame.K_r:
|
|
stop_music() # Stop music when returning to menu
|
|
self.manager.game_state = "menu"
|
|
self.manager.current_scene = Menu(self.manager)
|
|
|
|
def draw(self, screen):
|
|
screen.fill(BLACK)
|
|
font = pygame.font.Font(None, 100)
|
|
text = font.render("Game Over", True, RED)
|
|
text_rect = text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 3))
|
|
screen.blit(text, text_rect)
|
|
|
|
font = pygame.font.Font(None, 50)
|
|
score_text = font.render(f"Score: {self.manager.score}", True, WHITE)
|
|
score_rect = score_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2))
|
|
screen.blit(score_text, score_rect)
|
|
|
|
font = pygame.font.Font(None, 30)
|
|
continue_text = font.render("Press R to Restart or Click to continue", True, WHITE)
|
|
continue_rect = continue_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT * 2 // 3))
|
|
screen.blit(continue_text, continue_rect)
|
|
"" |