-1

I'm making a simple project for Pygame, which is basically intended to run as a text-based strategy/fighting game. I coded it just using Python, but now I'm trying to implement a GUI using Pygame (and expand on it eventually).

In this game, the player has a number of available moves depending on their current position (stored as an array). What I'm hoping to do is create and display a button for each of these moves that the user can choose from.

I know how to make a button, but I'm struggling to figure out how to add a button per move and constantly updates, based on the player's changing position.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174

1 Answers1

1

You basically want a Button class for that. That way you can create button objects, put them in a list and operate on them easily. Here is an example with a barely-even-a-button Button class just to get the point across. I have created a list with 4 buttons, but you can just as easily .append those buttons to dynamically create them according to the needs of your program.

import pygame
from sys import exit as _exit 

##just pygame stuff here. You can ignore them and go
##to the interesting things below

class PG_Widnow_UI:
    def __init__(self, width, height):
        pygame.init()
        self.widht = width
        self.height = height
        self.window = pygame.display.set_mode((width, height))

    def update(self):
        pygame.display.flip()

    def clear(self, r, g, b):
        self.window.fill((r, g, b))

    def close(self):
        pygame.quit()
        _exit()

        #handles events 
def handleEvents(events):
    exitGame = False
    for event in events:
        if event.type == pygame.QUIT:
            pg_window.close()

#Takes rectangle's size, position and a point. Returns true if that
#point is inside the rectangle and false if it isnt.
def pointInRectanlge(px, py, rw, rh, rx, ry):
    if px > rx and px < rx  + rw:
        if py > ry and py < ry + rh:
            return True
    return False


##=====================================================================##

#This class will act as a bllueprint for all the buttons in the game
class Button:
    def __init__(self, text:str, position:tuple
                 , size:tuple=(200, 50), outline:bool=True)->None:
        self.position = position
        self.size = size
        self.button = pygame.Surface(size).convert()
        self.button.fill((0, 0, 0))
        self.outline = outline

        #Text is about 70% the height of the button
        font = pygame.font.Font(pygame.font.get_default_font(), int((70/100)*self.size[1]))

        #First argument always requires a str, so f-string is used.
        self.textSurf = font.render(f"{text}", True, (255, 255, 255))

    def clicked(self, events)->None:
        mousePos = pygame.mouse.get_pos()
        if pointInRectanlge(mousePos[0], mousePos[1], self.size[0], self.size[1], self.position[0], self.position[1]):
            for event in events:
                if event.type == pygame.MOUSEBUTTONDOWN:
                    return True
        return False

    #Renders the button and text. Text position is calculated depending on position of button.
    #Also draws outline if self.outline is true
    def render(self, display:pygame.display)->None:
        #calculation to centre the text in button
        textx = self.position[0] + (self.button.get_rect().width/2) - (self.textSurf.get_rect().width/2)
        texty = self.position[1] + (self.button.get_rect().height/2) - (self.textSurf.get_rect().height/2)

        #display button first then text
        display.blit(self.button, (self.position[0], self.position[1]))
        display.blit(self.textSurf, (textx, texty))
        
        #draw outline
        if self.outline:
            thickness = 5
            posx = self.position[0] - thickness
            posy = self.position[1] - thickness
            sizex = self.size[0] + thickness * 2
            sizey = self.size[1] + thickness * 2

            pygame.draw.rect(display, (255, 0, 0), (posx, posy, sizex, sizey), thickness)


windowWidth = 1000
windowHeight = 500
pg_window = PG_Widnow_UI(windowWidth, windowHeight)

##LOOP TO ADD BUTTONS TO THE LIST 


number_of_buttons = 4
buttons = [Button(f"Button {i}", ((220 * (i%4) + 10), ((i % 4) * 70) + 10)) 
for i in range(number_of_buttons)]

while True:
    pg_window.clear(255, 255, 255)

    events = pygame.event.get()
    handleEvents(events)

    ##DRAWING THE BUTTONS 
    for button in buttons:
        button.render(pg_window.window)
        if button.clicked(events):
            print(f"button at position: {button.position} was  clicked") 
    
    pg_window.update()