UI System

The UI system in Medieval Deck is designed to be reusable and consistent across different game screens. The core of this system resides in utils/buttons.py.

Button Class

The Button class is a versatile, self-contained component for creating clickable UI elements. It manages its own state, rendering, and event handling.

Key Features:

  • State Management: Tracks its own is_hovered and is_clicked states.
  • Visual Feedback: Automatically changes its background color when the mouse hovers over it.
  • Event Handling: The handle_event method processes mouse events to update its state and detect clicks.
  • Styling: Can be customized with different text, fonts, colors, and dimensions.

Example usage:

# Creating a single button
confirm_font = pygame.font.Font(None, 60)
confirm_button = Button(
    x=100, y=100, width=300, height=80, 
    text="CONFIRMAR", font=confirm_font,
    color=GOLD
)

# In the event loop
if confirm_button.handle_event(event):
    print("Button clicked!")

# In the render loop
confirm_button.draw(screen)

To simplify the creation of vertically aligned menus, the MenuButtonSet class provides a manager for a group of buttons. It handles the layout and event delegation automatically.

Key Features:

  • Automatic Layout: Calculates the correct position for each button to create a centered, evenly spaced vertical list.
  • Simplified Event Handling: The handle_events method iterates through all buttons in the set, returning the text of any button that is clicked. This simplifies the event loop in the screen module.
  • Easy Creation: Buttons are added with a single call to add_button.

This class is used in screens/menu.py to create the main menu.

# From screens/menu.py

class MenuScreen:
    def __init__(self, game_instance):
        # ...
        self.button_set = MenuButtonSet(SCREEN_WIDTH, SCREEN_HEIGHT, self.button_font)
        self._setup_buttons()

    def _setup_buttons(self):
        """Setup menu buttons with callbacks"""
        self.button_set.add_button("JOGAR", self._start_game)
        self.button_set.add_button("OPÇÕES", self._show_options)
        self.button_set.add_button("SAIR", self._quit_game)

    def handle_events(self, events):
        clicked_button = self.button_set.handle_events(events)
        # ... logic based on clicked_button ...

This reusable system ensures that all buttons have a consistent look and feel while reducing boilerplate code in the screen modules.