为了账号安全,请及时绑定邮箱和手机立即绑定

我怎样才能使pygame中的按钮正常工作?(刽子手游戏)

我怎样才能使pygame中的按钮正常工作?(刽子手游戏)

慕慕森 2023-06-13 16:47:25
嗨,我是一个 python 菜鸟,我正在尝试自己用 pygame 制作一个刽子手游戏,同时尽可能避免来自 YouTube 教程的帮助。我的问题是:当我将鼠标悬停在按钮上时,按钮会改变颜色(这很好),但即使我仍在按钮上悬停,它也会变回原来的颜色。此外,将鼠标悬停在多个按钮上时,按钮的响应速度非常差。当我单击一个按钮时,程序认为我多次单击该按钮。print('clicked!')因为它多次执行该行。最后,当我点击一个按钮来 blit 一个精灵时,它只会短暂地 blit 精灵,然后它会自动取消 blit 自己。这是我的代码:import pygamepygame.init()# DISPLAYWIDTH, HEIGHT = 800, 500window = pygame.display.set_mode((WIDTH, HEIGHT))# TITLE BARTITLE = "Hangman"pygame.display.set_caption(TITLE)# HANGMAN SPRITESman = [pygame.image.load(f"hangman{frame}.png") for frame in range(0, 7)]class Button:    def __init__(self, color, x, y, radius, text=""):        self.radius = radius        self.color = color        self.x = x        self.y = y        self.width = 2        self.text = text        self.visible = True    def draw(self, window, outline=None):        if self.visible:            if outline:                # draws a bigger circle behind                pygame.draw.circle(window, outline, (self.x, self.y), self.radius + 2, 0)            pygame.draw.circle(window, self.color, (self.x, self.y), self.radius, 0)        if self.text != "":            if self.visible:                font = pygame.font.SysFont("courier", 30)                text = font.render(self.text, 1, (0, 0, 0))                window.blit(text, (self.x - text.get_width() / 2, self.y - text.get_height() / 2))    def hover(self, pos):        if self.y + self.radius > pos[1] > self.y - self.radius:            if self.x + self.radius > pos[0] > self.x - self.radius:                return True        return Falsedef main():    run = True    FPS = 60    clock = pygame.time.Clock()    large_font = pygame.font.SysFont("courier", 50)    letters = []    error = 0另外,我从 YouTube 上的 Tech With Tim Hangman 教程中获得了 sprite(我只是在没有看他编写游戏代码的情况下获得了 sprite,因为我想尝试自己做,这样我可以学到更多)。我也从 Tech With Tim 的视频中获得了按钮类的代码。
查看完整描述

2 回答

?
心有法竹

TA贡献1866条经验 获得超5个赞

首先在应用程序循环之前对按钮进行初始化,而不是在循环中连续进行


def main():


    # init buttons

    alphabet = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")

    letter_x1, letter_y1 = 40, 375

    letter_x2, letter_y2 = 40, 435

    for i in range(13):

        letter_1 = Button((255, 255, 255), letter_x1, letter_y1, 25, alphabet[i])

        letters.append(letter_1)

        letter_x1 += 60

    for i in range(13, 26):

        letter_2 = Button((255, 255, 255), letter_x2, letter_y2, 25, alphabet[i])

        letters.append(letter_2)

        letter_x2 += 60


    # application loop

    while run:

        # [...]

给按钮添加一个属性clicked,用来存储按钮(类似于visible属性):


class Button:


    def __init__(self, color, x, y, radius, text=""):

        # [...]


        self.visible = True

        self.clicked = False

设置属性,点击按钮时:


def main():

    # [...]


    while run:

        # [...]

        for event in pygame.event.get():

            # [...]

            elif event.type == pygame.MOUSEBUTTONDOWN:

                for letter in letters:

                    if letter.hover(pygame.mouse.get_pos()):

                        letter.clicked = True

现在您可以根据clicked按钮的状态绘制对象:


def main():

    # [...]


    def redraw_window():

        window.fill((255, 255, 255))

        

        window.blit(man[0], (20, 100))

        # DRAWS LETTER BUTTONS

        for letter in letters:

            letter.draw(window, (0, 0, 0))

             

            if letter.clicked:

                # [...]


        pygame.display.update()


    # [...]

    while run:

        redraw_window()

        # [...]        

或者或另外,您可以将单击的最后一个按钮存储到变量 ( lastLetterClicked) 并根据变量绘制一些内容:


def main():

    # [...]


    def redraw_window():

        # [...]


        if lastLetterClicked:

            # [...]


        pygame.display.update()


    lastLetterClicked = None

    while run:

        redraw_window()

        # [...]


        for event in pygame.event.get():

            # [...]

            elif event.type == pygame.MOUSEBUTTONDOWN:

                for letter in letters:

                    if letter.hover(pygame.mouse.get_pos()):

                        # [...]

                        lastLetterClicked = letter


        # [...]


查看完整回答
反对 回复 2023-06-13
?
回首忆惘然

TA贡献1847条经验 获得超11个赞

好的,让我们从第一个开始,我怀疑这里的一些变化也可能有助于解决其他问题。nonice,您正在“while run”循环中创建“初始彩色按钮”,这意味着它会一次又一次地发生,但是您在事件循环中对按钮进行了重新染色,这仅在出现新事件时才会发生。你看到问题了吗?悬停事件发生后的下一分钟,程序将绘制一个常规按钮!我会说这条线

  letter.color = (0, 255, 0)

在 OOP 中被认为是一个坏习惯,因为您不想在类之外更改对象属性。相反,让我们构建一个“set_color”方法

 def set_color(self , color):
     self.color = color

并启动按钮 letter_1 = Button((255, 255, 255), letter_x1, letter_y1, 25, alphabet[i])

在游戏开始之前,在 while 运行循环之外

在 while 循环中你可以只添加一个循环来绘制它们。

 for letrer in letters:
       letter.draw()


查看完整回答
反对 回复 2023-06-13
  • 2 回答
  • 0 关注
  • 129 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信