如何检测鼠标是否悬停在按钮上?PyGame 按钮类在悬停时不显示文本或更改颜色 [英] How do I detect if the mouse is hovering over a button? PyGame button class is not displaying the text or changing colour on hover
问题描述
我在 pygame 中创建了一个按钮类,虽然按钮本身正在显示,但我的文本没有显示.当鼠标悬停在按钮上时,我还有一些条件可以改变颜色.我在主函数中使用硬编码值实现了预期的结果,但是我想使用一个类来处理我的各种按钮,因为我可能有很多按钮.
下面是我正在使用的一些类
字体
类字体:def __init__(self, font, antialias, text, color, x, y):self.font = 字体self.antialias = 抗锯齿self.text = 文本self.color = 颜色自我.x = x自我.y = ydef draw(self, win):win.blit(self.font.render(self.text, self.antialias, (self.color)), (self.x, self.y))
按钮
class 按钮:def __init__(self, color, x, y, width, height, text, fontsize):self.color = 颜色自我.x = x自我.y = yself.width = 宽度self.height = 高度self.text = 文本self.fontsize = 字体大小self.courier_button_font = pygame.font.SysFont("Courier", self.fontsize)def draw(self, pos):x, y = 位置text_width, text_height = self.courier_button_font.size(self.text)如果 self.x <×<self.width 和 self.y
我使用按钮的功能
FireTowerButton = Button(BLACK, 810, 200, 80, 30, "Fire Tower", 20)def ShowTowers(鼠标):mousex, mousey = 鼠标screen.fill((147, 207, 14))FireTowerButton.draw(鼠标)定义主():运行 = 真屏幕填充(黑色)# screen.blit(enemy1, (90, 90))运行时:鼠标 = pygame.mouse.get_pos()ShowTowers(鼠标)screen.blit(money_image, (790, 0))screen.blit(background_image, (0, 0))敌人1_spawn(wave_number)pygame.draw.rect(屏幕,黑色,(770、75、30、90))对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:pygame.quit()出口()时钟滴答(FPS)pygame.display.update()
条件
<块引用>if self.x <×<self.width 和 self.y
错了.您必须评估 x
y
if self.x <×<self.x + self.width 和 self.y
无论如何,我推荐pygame.Rect
/collidepoint()
用于碰撞测试:
button_rect = pygame.Rect(self.x, self.y, self.width, self.height)如果 button_rect.collidepoint((x, y):# [...]
button_rect
可以进一步用于绘制矩形:
pygame.draw.rect(screen, (211, 211, 211), button_rect)
通过使用属性 rect
而不是单独的属性 x
, y
, 可以大大简化代码宽度
,高度
:
class 按钮:def __init__(self, color, x, y, width, height, text, fontsize):self.color = 颜色self.rect = pygame.Rect(x, y, 宽度, 高度)self.text = 文本self.fontsize = 字体大小self.courier_button_font = pygame.font.SysFont("Courier", self.fontsize)def draw(self, pos):button_color = (211, 211, 211) if self.rect.collidepoint(pos) else self.colorpygame.draw.rect(屏幕,button_color,self.rect)text_width, text_height = self.courier_button_font.size(self.text)textpos = (self.rect.centerx - text_width//2, self.rect.centery - text_height//2)buttontext = Fonts(courier_font, True, self.text, BLACK, textpos)buttontext.draw(屏幕)def isOver(self, pos):返回 self.rect.collidepoint(pos)
I have created a button class in pygame and although the button itself is displaying, my text is not showing up. Also I have some conditions to change the colour when the mouse is over the button. I have achieved the desired result using hard coded values in my main function, however I want to use a class the handle my various button as I might have quite a few buttons.
Given below are some classes that I'm using
Fonts
class Fonts:
def __init__(self, font, antialias, text, color, x, y):
self.font = font
self.antialias = antialias
self.text = text
self.color = color
self.x = x
self.y = y
def draw(self, win):
win.blit(self.font.render(self.text, self.antialias, (self.color)), (self.x, self.y))
Button
class Button:
def __init__(self, color, x, y, width, height, text, fontsize):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
self.fontsize = fontsize
self.courier_button_font = pygame.font.SysFont("Courier", self.fontsize)
def draw(self, pos):
x, y = pos
text_width, text_height = self.courier_button_font.size(self.text)
if self.x < x < self.width and self.y < y < self.height:
pygame.draw.rect(screen, (211, 211, 211), (self.x, self.y, self.width, self.height))
buttontext = Fonts(courier_font, True, f"{self.text}", BLACK,
int(self.width / 2 - text_width / 2), int(self.height / 2 - text_height / 2))
buttontext.draw(screen)
else:
pygame.draw.rect(screen, self.color, (self.x, self.y, self.width, self.height))
buttontext = Fonts(courier_font, True, f"{self.text}", BLACK,
(self.width / 2 - text_width / 2), (self.height / 2 - text_height / 2))
buttontext.draw(screen)
def isOver(self, pos):
x, y = pos
if self.x < x < self.width and self.y < y < self.height:
return True
else:
pass
The functions where I'm using my button
FireTowerButton = Button(BLACK, 810, 200, 80, 30, "Fire Tower", 20)
def ShowTowers(mouse):
mousex, mousey = mouse
screen.fill((147, 207, 14))
FireTowerButton.draw(mouse)
def main():
run = True
screen.fill(BLACK)
# screen.blit(enemy1, (90, 90))
while run:
mouse = pygame.mouse.get_pos()
ShowTowers(mouse)
screen.blit(money_image, (790, 0))
screen.blit(background_image, (0, 0))
enemy1_spawn(wave_number)
pygame.draw.rect(screen, BLACK, (770, 75, 30, 90))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
clock.tick(FPS)
pygame.display.update()
The condition
if self.x < x < self.width and self.y < y < self.height:
is wrong. You have to evaluate if x < self.x + self.width
and y < self.y + self.height
:
if self.x < x < self.x + self.width and self.y < y < self.y + self.height:
# [...]
Anyway, I recommend to pygame.Rect
/ collidepoint()
for the collision test:
button_rect = pygame.Rect(self.x, self.y, self.width, self.height)
if button_rect.collidepoint((x, y):
# [...]
button_rect
can be used further for drawing the rectangle:
pygame.draw.rect(screen, (211, 211, 211), button_rect)
The code can be simplified a lot by the use of an attribute rect
rather than the separate attributes x
, y
, width
, height
:
class Button:
def __init__(self, color, x, y, width, height, text, fontsize):
self.color = color
self.rect = pygame.Rect(x, y, width, height)
self.text = text
self.fontsize = fontsize
self.courier_button_font = pygame.font.SysFont("Courier", self.fontsize)
def draw(self, pos):
button_color = (211, 211, 211) if self.rect.collidepoint(pos) else self.color
pygame.draw.rect(screen, button_color, self.rect)
text_width, text_height = self.courier_button_font.size(self.text)
textpos = (self.rect.centerx - text_width // 2, self.rect.centery - text_height // 2)
buttontext = Fonts(courier_font, True, self.text, BLACK, textpos)
buttontext.draw(screen)
def isOver(self, pos):
return self.rect.collidepoint(pos)
这篇关于如何检测鼠标是否悬停在按钮上?PyGame 按钮类在悬停时不显示文本或更改颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!