python - 我的按钮操作似乎行为不端。该怎么做才能修复它或让它变得更好?
问题描述
我正在使用 Python 3.7.4 和 Pygame 1.9.6。这是我第一次使用 Python 中的面向对象;和创建按钮一样。我只是在测试这个,因为我想为我的 Space Invaders 游戏创建一个按钮。我只是不确定这是否是一种简单的方法或什么。当我想创建另一个按钮时。我只是做我对“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, 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), 20, 30, 20, '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, 0)
else:
play_again_button.color = (0, 255, 0)
无论如何,让我知道我是否应该做这样的按钮。我总是很感激反馈。
解决方案
Making a button as an object is a good idea because it makes the code easier to understand, as it wraps up all the button properties into a single data structure, with member functions to act on it.
There's a couple of bugs in your code but it's mostly OK.
When you create the button, you're passing too many parameters, and some are tuples rather than individual integers:
play_again_button = button((20, 20, 20), (340, 340), 20, 30, 20, 'Play again') # BROKEN
play_again_button = button((20, 20, 20), 340, 340, 20, 30, 'Play again') # FIXED
Where the code does the mouse-position check, it's passing 1
or 0
, and not the mouse event.pos
, this is an easy fix:
if play_again_button.isOver( 1 ):
if play_again_button.isOver( event.pos ): # FIXED
Similarly for the mouse click-check.
And Finally the screen-painting is being done in a reverse order, so that the buttons is drawn before the screen is erased, so you never see the button.
Below is code that works. I moved the offset border code inside the button class.
According to Python Style Guide PEP8, class-names Should Be Capitalised too.
Ref:
import pygame
class Button():
def __init__(self, color, x, y, width, height, text='', outline=(0,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, 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, 20 )
play_again_button = Button( DARK_GREY, 340, 340, 20, 30, '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, 0) )
else:
play_again_button.setColor( (0, 255, 0) )
screen.fill((255, 255, 255))
play_again_button.draw(screen)
pygame.display.update()
推荐阅读
- css - 如何将所有文本框对齐在一行中
- javascript - 为什么响应发送了两个标头?
- c# - 桌面应用程序的单向部分表同步
- vba - 仅当满足某些条件时,如何在 VBA 中弹出输入框?
- c# - xsd.exe 生成的文件没有基本类型
- pdf - 更改 PDF 阅读器中的 Firefox 后退按钮以带您返回上一个网页而不是 PDF 的第一页
- python-3.x - 使用 Pytest 进行单元测试时断言值 None 错误
- jenkins - 在 Jenkins Pipeline 的一个步骤中添加多个阶段
- java - 将 Java 7 更新为 Unlimited Strength Jurisdiction Policy 有哪些潜在问题?
- vue.js - 通过 Vue Router 渲染 html 文件