Files
pixel_tower_defense/game/game.py
T
2026-07-15 22:16:18 +02:00

91 lines
3.0 KiB
Python

"""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()