猿问

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

嗨,我是一个 python 菜鸟,我正在尝试自己用 pygame 制作一个刽子手游戏,同时尽可能避免来自 YouTube 教程的帮助。

我的问题是:

  1. 当我将鼠标悬停在按钮上时,按钮会改变颜色(这很好),但即使我仍在按钮上悬停,它也会变回原来的颜色。此外,将鼠标悬停在多个按钮上时,按钮的响应速度非常差。

  2. 当我单击一个按钮时,程序认为我多次单击该按钮。print('clicked!')因为它多次执行该行。

  3. 最后,当我点击一个按钮来 blit 一个精灵时,它只会短暂地 blit 精灵,然后它会自动取消 blit 自己。

这是我的代码:

import pygame

pygame.init()


# DISPLAY

WIDTH, HEIGHT = 800, 500

window = pygame.display.set_mode((WIDTH, HEIGHT))

# TITLE BAR

TITLE = "Hangman"

pygame.display.set_caption(TITLE)

# HANGMAN SPRITES

man = [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 False



def 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 的视频中获得了按钮类的代码。


慕慕森
浏览 179回答 2
2回答

心有法竹

首先在应用程序循环之前对按钮进行初始化,而不是在循环中连续进行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        # [...]

回首忆惘然

好的,让我们从第一个开始,我怀疑这里的一些变化也可能有助于解决其他问题。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()
随时随地看视频慕课网APP

相关分类

Python
我要回答