如何解决我如何在pygame中制作按钮? HANGMAN GAME
您好,我是python菜鸟,我想尝试自己通过pygame制作子手游戏,同时尽可能避免YouTube教程的帮助。
我的问题是:
-
当我将鼠标悬停在按钮上时,按钮会更改颜色(这很好),但是即使我仍将鼠标悬停在按钮上,它也会变回原来的颜色。另外,将鼠标悬停在多个按钮上时,按钮的响应性非常差。
-
当我单击一个按钮时,程序会认为我多次单击了该按钮。当它多次执行
print('clicked!')
行时。 -
最后,当我单击一个按钮来消灭精灵时,它只会消灭精灵一会儿,并且会自动消除其自身的消弱。
这是我的代码:
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.radius,0)
if self.text != "":
if self.visible:
font = pygame.font.SysFont("courier",30)
text = font.render(self.text,1,(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
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))
pygame.display.update()
while run:
redraw_window()
clock.tick(FPS)
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),letter_x1,letter_y1,25,alphabet[i])
letters.append(letter_1)
letter_x1 += 60
for i in range(13,26):
letter_2 = Button((255,letter_x2,letter_y2,alphabet[i])
letters.append(letter_2)
letter_x2 += 60
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == pygame.MOUSEMOTION:
for letter in letters[:]:
if letter.hover(pygame.mouse.get_pos()):
letter.color = (0,0)
else:
letter.color = (255,255)
elif event.type == pygame.MOUSEBUTTONDOWN:
for letter in letters:
if letter.hover(pygame.mouse.get_pos()):
print("clicked!")
window.blit(man[1],100))
pygame.display.update()
quit()
main()
此外,我从YouTube的Tim With Hangman教程中获得了精灵(我只是不看他编写游戏代码就得到了精灵,因为我想自己尝试做,以便我可以学习更多)。我也从Tech With Tim的视频中获得了按钮类的代码。
解决方法
首先在应用程序循环之前而不是在循环中进行按钮的初始化
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,letter_x2,letter_y2,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))
window.blit(man[0],(20,100))
# DRAWS LETTER BUTTONS
for letter in letters:
letter.draw(window,(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,您正在“运行时”循环内创建“初始彩色按钮”,这意味着它会再次发生,但是您将事件内的按钮重新循环用于循环,仅在出现新事件时才会发生。你看到问题了吗?悬停事件发生后的下一个分钟,程序将只绘制一个常规按钮! 我会说这行
letter.color = (0,0)
在OOP中被认为是一个坏习惯,因为您不想在类外更改对象属性。相反,让我们构建一个“ set_color”方法
def set_color(self,color):
self.color = color
并启动按钮 letter_1 = Button((255,255,255),letter_x1,letter_y1,25,字母[i])
在游戏开始之前,在while运行循环之外
在while循环中,您只需添加一个循环即可绘制它们。
for letrer in letters:
letter.draw()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。