import pygame from typing import List, Dict class UIPanels: def __init__(self, screen_width: int, screen_height: int): self.screen_width = screen_width self.screen_height = screen_height self.ui_commands = [] self.ui_state = { 'selected_units': [], 'build_queue': [], 'show_unit_panel': False, 'resources': {}, 'unit_panel_data': [] } def update(self, snapshot: Dict, input_commands: List[Dict]) -> List[Dict]: self.ui_commands = [] for cmd in input_commands: if cmd.get('type') == 'select': self._handle_selection(snapshot, cmd) elif cmd.get('type') == 'build': self._handle_build_command(cmd) self._update_resource_bar(snapshot) self._update_unit_panel(snapshot) self._update_build_queue(snapshot) return self.ui_commands def draw(self, surface: pygame.Surface) -> None: self._draw_resource_bar(surface) self._draw_unit_panel(surface) self._draw_build_queue(surface) def handle_click(self, pos: tuple) -> None: if self._is_build_queue_click(pos): self._handle_build_queue_click(pos) elif self._is_unit_panel_click(pos): self._handle_unit_panel_click(pos) def _handle_selection(self, snapshot: Dict, command: Dict) -> None: self.ui_state['selected_units'] = [] world_pos = command.get('world_pos', (0, 0)) entities = snapshot.get('entities', []) for entity in entities: if self._is_entity_at_position(entity, world_pos): if entity.get('owner') == 'player': self.ui_state['selected_units'].append(entity['id']) self.ui_state['show_unit_panel'] = len(self.ui_state['selected_units']) > 0 def _handle_build_command(self, command: Dict) -> None: building_type = command.get('building_type') if building_type: self.ui_commands.append({ 'type': 'create_entity', 'entity_type': building_type, 'position': self._get_default_build_position() }) def _update_resource_bar(self, snapshot: Dict) -> None: self.ui_state['resources'] = snapshot.get('resources', {}) def _update_unit_panel(self, snapshot: Dict) -> None: if not self.ui_state['show_unit_panel']: return selected_units = [] entities = snapshot.get('entities', []) for entity_id in self.ui_state['selected_units']: for entity in entities: if entity.get('id') == entity_id: selected_units.append(entity) break self.ui_state['unit_panel_data'] = selected_units def _update_build_queue(self, snapshot: Dict) -> None: entities = snapshot.get('entities', []) self.ui_state['build_queue'] = [entity for entity in entities if entity.get('build_progress', 1) < 1] def _draw_resource_bar(self, surface: pygame.Surface) -> None: bar_height = 40 bar_rect = pygame.Rect(0, 0, self.screen_width, bar_height) pygame.draw.rect(surface, (50, 50, 80), bar_rect) pygame.draw.rect(surface, (100, 100, 150), bar_rect, 2) font = pygame.font.Font(None, 24) minerals = self.ui_state['resources'].get('minerals', 0) gas = self.ui_state['resources'].get('gas', 0) resources_text = f"Resources: {minerals} Minerals | {gas} Gas" text_surface = font.render(resources_text, True, (255, 255, 255)) surface.blit(text_surface, (10, 10)) def _draw_unit_panel(self, surface: pygame.Surface) -> None: if not self.ui_state['show_unit_panel']: return panel_width = 300 panel_height = 200 panel_x = self.screen_width - panel_width panel_y = self.screen_height - panel_height panel_rect = pygame.Rect(panel_x, panel_y, panel_width, panel_height) pygame.draw.rect(surface, (60, 60, 90), panel_rect) pygame.draw.rect(surface, (100, 100, 150), panel_rect, 2) font = pygame.font.Font(None, 20) title_text = f"Selected Units: {len(self.ui_state.get('unit_panel_data', []))}" title_surface = font.render(title_text, True, (255, 255, 255)) surface.blit(title_surface, (panel_x + 10, panel_y + 10)) if self.ui_state.get('unit_panel_data'): unit = self.ui_state['unit_panel_data'][0] unit_info = f"Type: {unit.get('name', 'Unknown')} | Health: {unit.get('health', 0)}/{unit.get('max_health', 0)}" info_surface = font.render(unit_info, True, (200, 200, 200)) surface.blit(info_surface, (panel_x + 10, panel_y + 40)) if unit.get('type') == 'unit': build_button = pygame.Rect(panel_x + 10, panel_y + 70, 80, 30) pygame.draw.rect(surface, (80, 80, 120), build_button) build_text = font.render("Build", True, (255, 255, 255)) surface.blit(build_text, (panel_x + 20, panel_y + 75)) def _draw_build_queue(self, surface: pygame.Surface) -> None: panel_width = 200 panel_height = 150 panel_x = 0 panel_y = self.screen_height - panel_height panel_rect = pygame.Rect(panel_x, panel_y, panel_width, panel_height) pygame.draw.rect(surface, (60, 60, 90), panel_rect) pygame.draw.rect(surface, (100, 100, 150), panel_rect, 2) font = pygame.font.Font(None, 20) title_text = "Build Queue" title_surface = font.render(title_text, True, (255, 255, 255)) surface.blit(title_surface, (panel_x + 10, panel_y + 10)) build_queue = self.ui_state.get('build_queue', []) for i, entity in enumerate(build_queue[:3]): progress = entity.get('build_progress', 0) / entity.get('build_time', 1) item_text = f"{entity.get('name', 'Unknown')}: {progress:.0%}" item_surface = font.render(item_text, True, (200, 200, 200)) surface.blit(item_surface, (panel_x + 10, panel_y + 40 + i * 25)) def _is_entity_at_position(self, entity: Dict, world_pos: tuple) -> bool: if 'x' not in entity or 'y' not in entity: return False dx = entity['x'] - world_pos[0] dy = entity['y'] - world_pos[1] distance = (dx*dx + dy*dy) ** 0.5 return distance < 30 def _get_default_build_position(self) -> tuple: return (self.screen_width // 2, self.screen_height // 2) def _is_build_queue_click(self, pos: tuple) -> bool: panel_width = 200 panel_height = 150 panel_x = 0 panel_y = self.screen_height - panel_height panel_rect = pygame.Rect(panel_x, panel_y, panel_width, panel_height) return panel_rect.collidepoint(pos) def _is_unit_panel_click(self, pos: tuple) -> bool: if not self.ui_state['show_unit_panel']: return False panel_width = 300 panel_height = 200 panel_x = self.screen_width - panel_width panel_y = self.screen_height - panel_height panel_rect = pygame.Rect(panel_x, panel_y, panel_width, panel_height) return panel_rect.collidepoint(pos) def _handle_build_queue_click(self, pos: tuple) -> None: panel_width = 200 panel_height = 150 panel_x = 0 panel_y = self.screen_height - panel_height relative_y = pos[1] - panel_y if 40 <= relative_y <= 115: item_index = (relative_y - 40) // 25 build_queue = self.ui_state.get('build_queue', []) if item_index < len(build_queue): self.ui_commands.append({ 'type': 'cancel_build', 'entity_id': build_queue[item_index]['id'] }) def _handle_unit_panel_click(self, pos: tuple) -> None: panel_width = 300 panel_height = 200 panel_x = self.screen_width - panel_width panel_y = self.screen_height - panel_height relative_x = pos[0] - panel_x relative_y = pos[1] - panel_y if 10 <= relative_x <= 90 and 70 <= relative_y <= 100: self.ui_commands.append({ 'type': 'build', 'building_type': 'barracks' })