From 18bde75910094065db98d88edf6e60b294995fc7 Mon Sep 17 00:00:00 2001 From: Vincent Rodley Date: Thu, 21 Aug 2025 11:49:03 +1200 Subject: [PATCH] menu manager to make cleaner --- gui/game.py | 181 +++++++++++++++++++++++--------------------- gui/menu_manager.py | 31 ++++++++ 2 files changed, 127 insertions(+), 85 deletions(-) create mode 100644 gui/menu_manager.py diff --git a/gui/game.py b/gui/game.py index 0c07503..99a3ba6 100644 --- a/gui/game.py +++ b/gui/game.py @@ -1,129 +1,140 @@ -# Imports +# imports import pygame - from button import Button +from menu_manager import MenuManager -# some pygame constst +# consts WINDOW_SIZE = (768, 768) TARGET_FPS = 60 +COLS, ROWS = 7, 6 +TILE_SIZE, TILE_SPACING = 50, 20 -# pygame inits +GRID_WIDTH = COLS * TILE_SIZE + (COLS - 1) * TILE_SPACING +GRID_HEIGHT = ROWS * TILE_SIZE + (ROWS - 1) * TILE_SPACING + +# init the pygame pygame.init() font = pygame.font.Font("Baloo2-Bold.ttf", 40) display = pygame.display.set_mode(WINDOW_SIZE) clock = pygame.time.Clock() -# more variable inits -menu = "" +# variables tiles = [] -COLS = 7 -ROWS = 6 +menu_manager = MenuManager(display, (30, 30, 40)) # background color + +# colorss +primary_color = (70, 130, 180) # button background +hover_color = (51, 102, 145) # button hover +text_color = (245, 245, 245) # button text +tile_color = (200, 200, 200) # tile main +tile_hover = (170, 170, 170) # tile hover +tile_text = (50, 50, 50) # tile text +bg_color = (30, 30, 40) # main background # menu functions -def change_menu(targetMenu): - global menu - menu = targetMenu - display.fill(bg_color) - def start_game_func(*_): - change_menu("game") create_tiles() + menu_manager.change_menu("game") def settings_menu(*_): - change_menu("settings") + menu_manager.change_menu("settings") def go_back(*_): - change_menu("start") + menu_manager.change_menu("start") +# tile stuff def create_tiles(): global tiles tiles = [] + + start_x = (WINDOW_SIZE[0] - GRID_WIDTH) // 2 + start_y = (WINDOW_SIZE[1] - GRID_HEIGHT) // 2 + for c in range(COLS): for r in range(ROWS): + x = start_x + c * (TILE_SIZE + TILE_SPACING) + y = start_y + r * (TILE_SIZE + TILE_SPACING) + tile = Button( - 50*c+50, 50*r+50, 30, 30, str(len(tiles)), - tile_color, tile_hover, tile_text, tile_press, None, 30, (len(tiles),c,r), - rounding=5 - ) + x, y, TILE_SIZE, TILE_SIZE, str(len(tiles)), + tile_color, tile_hover, tile_text, tile_press, None, 30, (len(tiles), c, r), + rounding=5 + ) tiles.append(tile) -# gets called when you click on a tile def tile_press(tile): - tile_id,x,y = tile.extra_data + tile_id, x, y = tile.extra_data print(f"TILE {tile_id} at {x},{y} PRESSED") -# Main block + +# button stuff +width, height = 280, 75 +x = WINDOW_SIZE[0] / 2 - width / 2 +y = WINDOW_SIZE[1] / 2 - height / 2 + +start_button = Button(x, y - 100, width, height, "Start Game", + primary_color, hover_color, text_color, + start_game_func, "Baloo2-Bold.ttf", 50, rounding=8) + +settings_button = Button(x, y - 100 + height * 2, width, height, "Settings", + primary_color, hover_color, text_color, + settings_menu, "Baloo2-Bold.ttf", 50, rounding=8) + +go_back_button = Button(x, y, width, height, "Go back", + primary_color, hover_color, text_color, + go_back, "Baloo2-Bold.ttf", 50, rounding=8) + + +# menu handlers +# start +def start_menu_events(event): + start_button.handle_event(event) + settings_button.handle_event(event) + +def start_menu_draw(): + start_button.draw(display) + settings_button.draw(display) + +# settings +def settings_menu_events(event): + go_back_button.handle_event(event) + +def settings_menu_draw(): + text_surface = font.render("No settings yet :(", True, text_color) + text_rect = text_surface.get_rect(center=(WINDOW_SIZE[0] / 2, WINDOW_SIZE[1] / 2 - 100)) + display.blit(text_surface, text_rect) + go_back_button.draw(display) + +# game +def game_menu_events(event): + for tile in tiles: + tile.handle_event(event) + +def game_menu_draw(): + for tile in tiles: + tile.draw(display) + +# register the menus +menu_manager.register_menu("start", start_menu_events, start_menu_draw) +menu_manager.register_menu("settings", settings_menu_events, settings_menu_draw) +menu_manager.register_menu("game", game_menu_events, game_menu_draw) + +menu_manager.change_menu("start") + + +# main loopy loopy if __name__ == "__main__": - # You're running the game, therefore running = True running = True - # Button inits - width = 280 - height = 75 - - x = WINDOW_SIZE[0] / 2 - width / 2 # center of the screen horizontally - y = WINDOW_SIZE[1] / 2 - height / 2 # center of the screen vertically - - primary_color = (70, 130, 180) # button background - hover_color = (51, 102, 145) # button hover - text_color = (245, 245, 245) # button text - tile_color = (200, 200, 200) # tile main - tile_hover = (170, 170, 170) # tile hover - tile_text = (50, 50, 50) # tile text - bg_color = (30, 30, 40) # main background - - start_button = Button(x, y - 100, width, height, "Start Game", primary_color, hover_color, text_color, start_game_func, "Baloo2-Bold.ttf", 50, rounding=8) - settings_button = Button(x, y-100+height*2, width, height, "Settings", primary_color, hover_color, text_color, settings_menu, "Baloo2-Bold.ttf", 50, rounding=8) - go_back_button = Button(x, y, width, height, "Go back", primary_color, hover_color, text_color, go_back, "Baloo2-Bold.ttf", 50, rounding=8) - - change_menu("start") - - # Game loop while running: - - # handles user input for event in pygame.event.get(): - # Lets you actually close the game, or ESC out if event.type == pygame.QUIT: running = False - if event.type == pygame.KEYDOWN: - if event.key == pygame.K_ESCAPE: - running = False - - # Handles all the inputs for the buttons - if menu == "start": - start_button.handle_event(event) - settings_button.handle_event(event) - elif menu == "settings": - go_back_button.handle_event(event) - elif menu == "game": - for tile in tiles: - tile.handle_event(event) - else: - # very descriptive error message - print("You broke smth idek what tbh") + if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: running = False - - # Display stuff! - # so depending on what menu you're in, draw different stuff - if menu == "start": - start_button.draw(display) - settings_button.draw(display) - elif menu == "settings": - text_surface = font.render("No settings yet :(", True, text_color) - text_rect = text_surface.get_rect(center=(WINDOW_SIZE[0] / 2, WINDOW_SIZE[1] / 2 - 100)) - display.blit(text_surface, text_rect) - go_back_button.draw(display) - # basic connect-4 ahh grid - elif menu == "game": - for tile in tiles: - tile.draw(display) - else: - # very descriptive error msg - print("you broke smth.") - running = False + menu_manager.handle_event(event) - # flip the display and clock the tick so stuff actually updates + menu_manager.draw() pygame.display.flip() clock.tick(TARGET_FPS) diff --git a/gui/menu_manager.py b/gui/menu_manager.py new file mode 100644 index 0000000..f405a5f --- /dev/null +++ b/gui/menu_manager.py @@ -0,0 +1,31 @@ +import pygame + +class MenuManager: + def __init__(self, display, bg_color): + self.display = display + self.bg_color = bg_color + self.current_menu = None + self.event_handlers = {} + self.draw_handlers = {} + + # switch menu, and clear the screen + def change_menu(self, name): + if name not in self.draw_handlers: + raise ValueError(f"Menu: '{name} not registered") + self.current_menu = name + self.display.fill(self.bg_color) + + # register a menus event and draw functions + def register_menu(self, name, event_handler, draw_handler): + self.event_handlers[name] = event_handler + self.draw_handlers[name] = draw_handler + + # pass event to the menu handler + def handle_event(self, event): + if self.current_menu in self.event_handlers: + self.event_handlers[self.current_menu](event) + + # draw the current menu + def draw(self): + if self.current_menu in self.draw_handlers: + self.draw_handlers[self.current_menu]()