微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 Pygame 动态创建按钮?

如何解决如何使用 Pygame 动态创建按钮?

我正在为 Pygame 制作一个简单的项目,它基本上旨在作为基于文本的策略/格斗游戏运行。我只是使用 Python 对其进行编码,但现在我正在尝试使用 Pygame 实现一个 GUI(并最终对其进行扩展)。

在这个游戏中,玩家有许多可用的动作,取决于他们当前的位置(存储为数组)。我希望做的是为用户可以选择的每个动作创建并显示一个按钮。

我知道如何制作按钮,但我正在努力弄清楚如何根据玩家的位置变化在每次移动和不断更新时添加一个按钮。

任何建议或提示都会很棒!

解决方法

您基本上想要一个 Button 类。这样您就可以创建按钮对象,将它们放在列表中并轻松对其进行操作。这是一个带有几乎没有按钮的 Button 类的示例,只是为了说明这一点。我创建了一个包含 4 个按钮的列表,但您可以轻松地.append 这些按钮,根据程序的需要动态创建它们。

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,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))
        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,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)

    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() 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。