"""Game module - core game loop, screen management, and shared asset loading.""" import pygame_gui import pygame from game.util import load_image, load_images, load_images_alpha, Animation from game.tilemap import Tilemap from game.screens.main_menu import MainMenu from game.screens.game_play import GamePlay #constants FPS=60 WINDOW_SIZE=(960,540) class Game: """Central game class managing the loop, screens, and shared resources. Attributes: window (pygame.Surface): The main display surface. clock (pygame.time.Clock): Controls the frame rate. ui_manager (pygame_gui.UIManager): Manages all pygame_gui UI elements. tilemap (Tilemap): The active tilemap instance. assets (dict): Shared images and animations, keyed by name. screens (dict): All available screens, keyed by name. current_screen: The screen currently being updated and drawn. """ def __init__(self): pygame.init() self.window = pygame.display.set_mode(WINDOW_SIZE) self.clock = pygame.time.Clock() self.ui_manager = pygame_gui.UIManager( WINDOW_SIZE, "assets/theme/theme.json" ) self.tilemap = Tilemap(self) self.assets={ "base": load_images('/tiles/test'), "jungle": load_images('/tiles/jungle'), "desert": load_images('/tiles/desert'), "enemy": load_image('/entities/enemies/enemy.png'), "cannon": load_image('/entities/towers/cannon/shoot/0.png'), "red_cannon": load_image('/entities/towers/cannon/red_cannon.png'), "cannon/shoot": Animation(load_images_alpha('/entities/towers/cannon/shoot'), 10, False) } self.screens = { "menu": MainMenu(self), "game": GamePlay(self) } self.current_screen = self.screens["menu"] def change_screen(self, name): """Transition to a different screen by name. Hides the current screen and shows the requested one. Args: name (str): Key of the screen to switch to (e.g. ``"menu"``, ``"game"``). """ self.current_screen.hide() self.current_screen = self.screens[name] self.current_screen.show() def run(self): """Start the main game loop and block until the window is closed. Each iteration: processes events, updates state, and draws the frame. """ running = True while running: dt = self.clock.tick(FPS) / 1000.0 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False self.ui_manager.process_events(event) self.current_screen.process_event(event) self.current_screen.update(dt) self.ui_manager.update(dt) self.window.fill((20, 20, 20)) self.current_screen.draw(self.window) self.ui_manager.draw_ui(self.window) pygame.display.update() pygame.quit()