AI-Snake-Game/src/menu.py

129 lines
4.8 KiB
Python

import pygame
from enum import Enum, auto
from typing import List, Tuple, Callable
class GameMode(Enum):
PLAYER = auto()
AI_EASY = auto()
AI_MEDIUM = auto()
AI_HARD = auto()
QUIT = auto()
class MenuItem:
def __init__(self, text, position, action, size=36, color=(255, 255, 255)):
self.text = text
self.position = position
self.action = action
self.size = size
self.color = color
self.hover = False
self._setup_font()
def _setup_font(self):
self.font = pygame.font.Font(None, self.size)
self.surface = self.font.render(self.text, True, self.color)
self.rect = self.surface.get_rect(center=self.position)
def update_hover(self, mouse_pos):
self.hover = self.rect.collidepoint(mouse_pos)
if self.hover:
self.color = (255, 255, 0) # Yellow on hover
else:
self.color = (255, 255, 255) # White normally
self._setup_font()
def draw(self, screen):
screen.blit(self.surface, self.rect)
class Menu:
def __init__(self, width, height):
self.width = width
self.height = height
self.setup_menu_items()
self.title_font = pygame.font.Font(None, 72)
self.subtitle_font = pygame.font.Font(None, 36)
# Create title surfaces
self.title_surface = self.title_font.render("AI Snake Game", True, (0, 255, 0))
self.title_rect = self.title_surface.get_rect(center=(width//2, height//4))
self.subtitle_surface = self.subtitle_font.render("Choose Game Mode", True, (200, 200, 200))
self.subtitle_rect = self.subtitle_surface.get_rect(center=(width//2, height//4 + 50))
def setup_menu_items(self):
# Calculate positions for menu items
start_y = self.height // 2
spacing = 50
center_x = self.width // 2
self.menu_items = [
MenuItem("Player Mode", (center_x, start_y), GameMode.PLAYER),
MenuItem("AI Easy", (center_x, start_y + spacing), GameMode.AI_EASY),
MenuItem("AI Medium", (center_x, start_y + spacing * 2), GameMode.AI_MEDIUM),
MenuItem("AI Hard", (center_x, start_y + spacing * 3), GameMode.AI_HARD),
MenuItem("Quit", (center_x, start_y + spacing * 4), GameMode.QUIT, color=(255, 100, 100))
]
def handle_input(self, event):
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
mouse_pos = pygame.mouse.get_pos()
for item in self.menu_items:
if item.rect.collidepoint(mouse_pos):
return item.action
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
# Find the currently hovered item
for item in self.menu_items:
if item.hover:
return item.action
elif event.key in (pygame.K_UP, pygame.K_DOWN):
# Find current hover index
current_hover = -1
for i, item in enumerate(self.menu_items):
if item.hover:
current_hover = i
break
# Move hover up or down
if current_hover == -1:
new_hover = 0
else:
if event.key == pygame.K_UP:
new_hover = (current_hover - 1) % len(self.menu_items)
else:
new_hover = (current_hover + 1) % len(self.menu_items)
# Update hover states
for i, item in enumerate(self.menu_items):
item.hover = (i == new_hover)
item._setup_font()
return None
def update(self):
mouse_pos = pygame.mouse.get_pos()
for item in self.menu_items:
item.update_hover(mouse_pos)
def draw(self, screen):
# Draw background
screen.fill((0, 0, 0))
# Draw title and subtitle
screen.blit(self.title_surface, self.title_rect)
screen.blit(self.subtitle_surface, self.subtitle_rect)
# Draw menu items
for item in self.menu_items:
item.draw(screen)
# Draw version and controls
version_text = "v0.1.0"
controls_text = "Arrow keys to navigate, Enter to select"
font = pygame.font.Font(None, 24)
version_surface = font.render(version_text, True, (100, 100, 100))
controls_surface = font.render(controls_text, True, (100, 100, 100))
screen.blit(version_surface, (10, self.height - 30))
screen.blit(controls_surface, (self.width - controls_surface.get_width() - 10, self.height - 30))