我的按钮操作似乎异常如何解决它或使其变得更好?

问题描述

我正在使用Python 3.7.4和Pygame 1.9.6。这是我第一次使用面向Python的对象。与创建按钮相同。我正在测试这一点,因为我想为“太空侵略者”游戏创建一个按钮。我只是不确定这是否是一种简单的方法或执行什么操作。当我想创建另一个按钮时。我是否只是使用“ play_again_button”做过什么。

我想到了:

import pygame
class button():
    def __init__(self,color,x,y,width,height,text=''):
        self.color = color
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.text = text

    def draw(self,screen,outline=None):
        # Call this method to draw the button on the screen
        if outline:
            pygame.draw.rect(screen,outline,(self.x - 2,self.y - 2,self.width + 4,self.height + 4),0)

        pygame.draw.rect(screen,self.color,(self.x,self.y,self.width,self.height),0)

        if self.text != '':
            font = pygame.font.SysFont('freesansbold.ttf',60)
            text = font.render(self.text,1,(0,0))
            screen.blit(text,(
                self.x + (self.width / 2 - text.get_width() / 2),self.y + (self.height / 2 - text.get_height() / 2)))

    def isOver(self,pos):
        # Pos is the mouse position or a tuple of (x,y) coordinates
        if self.x < pos[0] < self.x + self.width:
            if self.y < pos[1] < self.y + self.height:
                return True

        return False


pygame.init()
screen = pygame.display.set_mode((800,600))

running = True
play_again_button = button((20,20,20),(340,340),30,'Play again')
while running:
    pygame.display.update()
    play_again_button.draw(screen)
    screen.fill((255,255,255))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            if play_again_button.isOver(1):
                print("Clicked button")
        if event.type == pygame.MOUSEMOTION:
            if play_again_button.isOver(0):
                play_again_button.color = (255,0)
            else:
                play_again_button.color = (0,0)

无论如何,无论如何都要让我知道。我总是很感谢您的反馈。

解决方法

将按钮作为对象是一个好主意,因为它将所有按钮属性包装到一个数据结构中,并使成员函数起作用,从而使代码更易于理解。

您的代码中有几个错误,但大多数情况下都可以。

创建按钮时,您传递的参数太多,有些是元组而不是单个整数:

play_again_button = button((20,20,20),(340,340),30,'Play again') # BROKEN

play_again_button = button((20,340,'Play again')       # FIXED

在代码执行鼠标位置检查的地方,它传递的是10,而不是鼠标的event.pos,这很容易解决:

if play_again_button.isOver( 1 ):

if play_again_button.isOver( event.pos ):   # FIXED

类似于鼠标单击检查。

最后,屏幕绘制以相反的顺序进行,以便在擦除屏幕之前绘制按钮,因此您永远不会看到按钮。

下面是有效的代码。我将偏移边界代码移到了按钮类中。

根据Python样式指南PEP8,类名也应大写。

参考:

import pygame

class Button():
    def __init__(self,color,x,y,width,height,text='',outline=(0,0)):
        self.color   = color
        self.x       = x
        self.y       = y
        self.width   = width
        self.height  = height
        self.text    = text
        self.outline = outline

    def draw(self,screen):
        # Call this method to draw the button on the screen
        if self.outline:
            pygame.draw.rect(screen,self.outline,(self.x - 2,self.y - 2,self.width + 4,self.height + 4),0 )

        pygame.draw.rect(screen,self.color,(self.x,self.y,self.width,self.height),0)

        if self.text != '':
            font = pygame.font.SysFont('freesansbold.ttf',60)
            text = font.render(self.text,1,(0,0))
            screen.blit(text,(
                self.x + int(self.width / 2 - text.get_width() / 2),self.y + int(self.height / 2 - text.get_height() / 2)))

    def setColor( self,new_colour ):
        self.color = new_color

    def isOver(self,pos):
        # Pos is the mouse position or a tuple of (x,y) coordinates
        if self.x < pos[0] < self.x + self.width:
            if self.y < pos[1] < self.y + self.height:
                return True

        return False


pygame.init()
screen = pygame.display.set_mode((800,600))

running = True
DARK_GREY=  ( 20,20 )
play_again_button = Button( DARK_GREY,'Play again')

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            if play_again_button.isOver( event.pos ):
                print("Clicked button")
        if event.type == pygame.MOUSEMOTION:
            if play_again_button.isOver( event.pos ):
                play_again_button.setColor( (255,0) )
            else:
                play_again_button.setColor( (0,255,0) )

    screen.fill((255,255))
    play_again_button.draw(screen)
    pygame.display.update()