当我将鼠标悬停在 pygame 中的按钮上时,如何弹出一个文本框
How do i make a text box pop up when i hover over a button in pygame
我希望能够在我将鼠标悬停在按钮上时弹出一个文本框,现在当我将鼠标悬停在按钮上时按钮会改变颜色但没有显示文本框我该如何实现或我需要到完全不同的东西,比如当我将鼠标悬停在任何一种方式上时弹出一个新屏幕悬停不起作用,我不知道如何修复它和 id 喜欢一些帮助
import pygame
pygame.init()
pygame.font.init()
colours = {"White" : (255, 255, 255), "Black" : (0, 0, 0), "Red" : (255, 0, 0), "Blue" : (0, 0, 255), "Green" : (0, 255, 0)}
orighpamt = 10
currentGoblin = 0
class Screen():
def __init__(self, title, width=400, height=600, fill=colours["White"]):
self.title=title
self.width=width
self.height = height
self.fill = fill
self.current = False
def makeCurrent(self):
pygame.display.set_caption(self.title)
self.current = True
self.screen = pygame.display.set_mode((self.width, self.height))
def endCurrent(self):
self.current = False
def checkUpdate(self):
return self.current
def screenUpdate(self):
if(self.current):
self.screen.fill(self.fill)
def returnTitle(self):
return self.screen
class Button():
def __init__(self, x, y, sx, sy, bcolour, fbcolour, font, fontsize, fcolour, text):
self.x = x
self.y = y
self.sx = sx
self.sy = sy
self.bcolour = bcolour
self.fbcolour = fbcolour
self.fcolour = fcolour
self.fontsize = fontsize
self.text = text
self.current = False
self.buttonf = pygame.font.SysFont(font, fontsize)
def showButton(self, display):
if(self.current):
pygame.draw.rect(display, self.fbcolour, (self.x, self.y, self.sx, self.sy))
else:
pygame.draw.rect(display, self.bcolour, (self.x, self.y, self.sx, self.sy))
textsurface = self.buttonf.render(self.text, False, self.fcolour)
display.blit(textsurface, ((self.x + (self.sx/2) - (self.fontsize/2)*(len(self.text)/2) - 5,(self.y + (self.sy/2) -(self.fontsize/2) - 4))))
def focusCheck(self, mousepos, mouseclick):
if(mousepos[0] >= self.x and mousepos[0] <= self.x + self.sx and mousepos[1] >= self.y and mousepos[1] <= self.y + self.sy):
self.current = True
return mouseclick
else:
self.current = False
return False
class Enemy(pygame.sprite.Sprite):
def __init__(self, dx, dy, filename):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(filename).convert()
self.rect = self.image.get_rect()
self.rect.x = dx
self.rect.y = dy
def draw(self, screen):
screen.blit(self.image, self.rect)
menuScreen = Screen("Menu Screen")
screen2 = Screen("Screen 2")
win = menuScreen.makeCurrent()
done = False
font = pygame.font.Font('freesansbold.ttf', 32)
clickdamage = 1
hitpoints = orighpamt
DungeonButton = Button(125, 500, 150, 50, colours["Black"], colours["Blue"], "arial", 20, colours["White"], "Dungeon")
hitboxButton = Button(80, 50, 280, 400, colours["White"], colours["Red"], "arial", 20, colours["White"], "")
hitpointamount = Button(100, 0, 200, 50, colours["White"], colours["Black"], "arial", 20, colours["Black"], str(hitpoints))
shopButton = Button(125, 500, 150, 50, colours["Black"], colours["Red"], "arial", 20, colours["White"], "Shop")
Assassin_Text = Button(50, 350, 400, 50, colours["White"], colours["Red"], "arial", 18, colours["Black"], "Sharpen your sword and increase your damage per click")
Assassin_Upgrade = Button(10, 300, 125, 50, colours["Black"], colours["Red"], "arial", 15, colours["White"], "Assassin")
goblin = Enemy(0 , 20, "images\goblin-resized.png")
goblin2 = Enemy(80 , 50, "images\monster2.png")
toggle = False
while not done:
menuScreen.screenUpdate()
screen2.screenUpdate()
mouse_pos = pygame.mouse.get_pos()
keys = pygame.key.get_pressed()
mouse_click = False
for event in pygame.event.get():
if(event.type == pygame.QUIT):
done = True
if event.type == pygame.MOUSEBUTTONDOWN:
mouse_click = True
if menuScreen.checkUpdate():
screen2button = shopButton.focusCheck(mouse_pos, mouse_click)
shopButton.showButton(menuScreen.returnTitle())
if screen2button:
win = screen2.makeCurrent()
menuScreen.endCurrent()
elif screen2.checkUpdate():
returnm = DungeonButton.focusCheck(mouse_pos, mouse_click)
Assassin_Upgrade.showButton(screen2.returnTitle())
if Assassin_Upgrade.focusCheck(mouse_pos):
Assassin_Text.showButton(screen2.returnTitle())
if returnm:
win = menuScreen.makeCurrent()
screen2.endCurrent()
pygame.display.update()
pygame.quit()
回答提供 Minimal, Reproducible Example 的问题更容易。您的示例具有外部图像和字体依赖项,需要克服这些依赖项才能让其他人调试您的代码。
如果您的按钮有关联的矩形,那么您可以使用 Rect.colliderect(position) 判断鼠标光标是否悬停在按钮上。
这是一个最小的示例,显示鼠标位于矩形中时的一些悬停文本:
import pygame
WIDTH = 640
HEIGHT = 480
FPS = 30
pygame.init()
pygame.font.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption(f"Color: purple")
clock = pygame.time.Clock()
# create a centered rectangle to fill with color
color_rect = pygame.Rect(100, 100, WIDTH - 200, HEIGHT - 200)
font = pygame.font.SysFont(None, 50, True)
msg = " Hovering Message "
hover_surface = font.render(msg, True, pygame.Color("chartreuse"), pygame.Color("firebrick"))
hovering = False
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# update game elements - Get mouse position
mx, my = pygame.mouse.get_pos()
# draw surface - fill background
screen.fill(pygame.Color("grey"))
## draw central rect
screen.fill(pygame.Color("purple"), color_rect)
## display the hovering text if the mouse is over the rectangle
if color_rect.collidepoint((mx, my)):
screen.blit(hover_surface, (mx, my))
# show surface
pygame.display.update()
# limit frames
clock.tick(FPS)
pygame.quit()
您的代码使用了大量的原始几何计算,在长 运行 中使用一些本机 pygame 元素可能更容易。例如,您可以将您的按钮设为不可移动的 Sprites,并将它们放在一个 Sprite 组中,以便于管理它们。
为您的 class 添加另一个文本属性。例如:
class Button():
def __init__(self, x, y, sx, sy, bcolour, fbcolour, font, fontsize, fcolour, text, tiptext):
# [...]
self.tiptextsurface = self.buttonf.render(tiptext, False, (0, 0, 0), (255, 255, 0))
在 Button.showTip
方法中绘制文本,当设置 self.current
时:
class Button():
# [...]
def showTip(self, display):
if self.current:
mouse_pos = pygame.mouse.get_pos()
display.blit(self.tiptextsurface, (mouse_pos[0]+16, mouse_pos[1]))
基于您的代码的最小示例:
我已经简化了 Button
class,但它的行为与您问题中的 class 完全一样。
import pygame
pygame.init()
class Button():
def __init__(self, x, y, sx, sy, bcolour, fbcolour, font, fontsize, fcolour, text, tiptext):
self.rect = pygame.Rect(x, y, sx, sy)
self.bcolour = bcolour
self.fbcolour = fbcolour
self.fcolour = fcolour
self.fontsize = fontsize
self.current = False
self.buttonf = pygame.font.SysFont(font, fontsize)
self.textsurface = self.buttonf.render(text, False, self.fcolour)
self.tiptextsurface = self.buttonf.render(tiptext, False, (0, 0, 0), (255, 255, 0))
def showButton(self, display):
color = self.fbcolour if self.current else self.bcolour
pygame.draw.rect(display, color, self.rect)
display.blit(self.textsurface, self.textsurface.get_rect(center = self.rect.center))
def showTip(self, display):
if self.current:
mouse_pos = pygame.mouse.get_pos()
display.blit(self.tiptextsurface, (mouse_pos[0]+16, mouse_pos[1]))
def focusCheck(self, mousepos, mouseclick):
self.current = self.rect.collidepoint(mousepos)
return mouseclick if self.current else True
screen = pygame.display.set_mode((400, 600))
clock = pygame.time.Clock()
font = pygame.font.Font('freesansbold.ttf', 32)
shopButton = Button(125, 500, 150, 50, "black", "red", "arial", 20, "white", "Shop", "Enter the shop")
done = False
while not done:
clock.tick(60)
for event in pygame.event.get():
if(event.type == pygame.QUIT):
done = True
if event.type == pygame.MOUSEBUTTONDOWN:
mouse_click = True
mouse_pos = pygame.mouse.get_pos()
mouse_click = False
screen2button = shopButton.focusCheck(mouse_pos, mouse_click)
screen.fill((255, 255, 255))
shopButton.showButton(screen)
shopButton.showTip(screen)
pygame.display.update()
pygame.quit()
我希望能够在我将鼠标悬停在按钮上时弹出一个文本框,现在当我将鼠标悬停在按钮上时按钮会改变颜色但没有显示文本框我该如何实现或我需要到完全不同的东西,比如当我将鼠标悬停在任何一种方式上时弹出一个新屏幕悬停不起作用,我不知道如何修复它和 id 喜欢一些帮助
import pygame
pygame.init()
pygame.font.init()
colours = {"White" : (255, 255, 255), "Black" : (0, 0, 0), "Red" : (255, 0, 0), "Blue" : (0, 0, 255), "Green" : (0, 255, 0)}
orighpamt = 10
currentGoblin = 0
class Screen():
def __init__(self, title, width=400, height=600, fill=colours["White"]):
self.title=title
self.width=width
self.height = height
self.fill = fill
self.current = False
def makeCurrent(self):
pygame.display.set_caption(self.title)
self.current = True
self.screen = pygame.display.set_mode((self.width, self.height))
def endCurrent(self):
self.current = False
def checkUpdate(self):
return self.current
def screenUpdate(self):
if(self.current):
self.screen.fill(self.fill)
def returnTitle(self):
return self.screen
class Button():
def __init__(self, x, y, sx, sy, bcolour, fbcolour, font, fontsize, fcolour, text):
self.x = x
self.y = y
self.sx = sx
self.sy = sy
self.bcolour = bcolour
self.fbcolour = fbcolour
self.fcolour = fcolour
self.fontsize = fontsize
self.text = text
self.current = False
self.buttonf = pygame.font.SysFont(font, fontsize)
def showButton(self, display):
if(self.current):
pygame.draw.rect(display, self.fbcolour, (self.x, self.y, self.sx, self.sy))
else:
pygame.draw.rect(display, self.bcolour, (self.x, self.y, self.sx, self.sy))
textsurface = self.buttonf.render(self.text, False, self.fcolour)
display.blit(textsurface, ((self.x + (self.sx/2) - (self.fontsize/2)*(len(self.text)/2) - 5,(self.y + (self.sy/2) -(self.fontsize/2) - 4))))
def focusCheck(self, mousepos, mouseclick):
if(mousepos[0] >= self.x and mousepos[0] <= self.x + self.sx and mousepos[1] >= self.y and mousepos[1] <= self.y + self.sy):
self.current = True
return mouseclick
else:
self.current = False
return False
class Enemy(pygame.sprite.Sprite):
def __init__(self, dx, dy, filename):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(filename).convert()
self.rect = self.image.get_rect()
self.rect.x = dx
self.rect.y = dy
def draw(self, screen):
screen.blit(self.image, self.rect)
menuScreen = Screen("Menu Screen")
screen2 = Screen("Screen 2")
win = menuScreen.makeCurrent()
done = False
font = pygame.font.Font('freesansbold.ttf', 32)
clickdamage = 1
hitpoints = orighpamt
DungeonButton = Button(125, 500, 150, 50, colours["Black"], colours["Blue"], "arial", 20, colours["White"], "Dungeon")
hitboxButton = Button(80, 50, 280, 400, colours["White"], colours["Red"], "arial", 20, colours["White"], "")
hitpointamount = Button(100, 0, 200, 50, colours["White"], colours["Black"], "arial", 20, colours["Black"], str(hitpoints))
shopButton = Button(125, 500, 150, 50, colours["Black"], colours["Red"], "arial", 20, colours["White"], "Shop")
Assassin_Text = Button(50, 350, 400, 50, colours["White"], colours["Red"], "arial", 18, colours["Black"], "Sharpen your sword and increase your damage per click")
Assassin_Upgrade = Button(10, 300, 125, 50, colours["Black"], colours["Red"], "arial", 15, colours["White"], "Assassin")
goblin = Enemy(0 , 20, "images\goblin-resized.png")
goblin2 = Enemy(80 , 50, "images\monster2.png")
toggle = False
while not done:
menuScreen.screenUpdate()
screen2.screenUpdate()
mouse_pos = pygame.mouse.get_pos()
keys = pygame.key.get_pressed()
mouse_click = False
for event in pygame.event.get():
if(event.type == pygame.QUIT):
done = True
if event.type == pygame.MOUSEBUTTONDOWN:
mouse_click = True
if menuScreen.checkUpdate():
screen2button = shopButton.focusCheck(mouse_pos, mouse_click)
shopButton.showButton(menuScreen.returnTitle())
if screen2button:
win = screen2.makeCurrent()
menuScreen.endCurrent()
elif screen2.checkUpdate():
returnm = DungeonButton.focusCheck(mouse_pos, mouse_click)
Assassin_Upgrade.showButton(screen2.returnTitle())
if Assassin_Upgrade.focusCheck(mouse_pos):
Assassin_Text.showButton(screen2.returnTitle())
if returnm:
win = menuScreen.makeCurrent()
screen2.endCurrent()
pygame.display.update()
pygame.quit()
回答提供 Minimal, Reproducible Example 的问题更容易。您的示例具有外部图像和字体依赖项,需要克服这些依赖项才能让其他人调试您的代码。
如果您的按钮有关联的矩形,那么您可以使用 Rect.colliderect(position) 判断鼠标光标是否悬停在按钮上。
这是一个最小的示例,显示鼠标位于矩形中时的一些悬停文本:
import pygame
WIDTH = 640
HEIGHT = 480
FPS = 30
pygame.init()
pygame.font.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption(f"Color: purple")
clock = pygame.time.Clock()
# create a centered rectangle to fill with color
color_rect = pygame.Rect(100, 100, WIDTH - 200, HEIGHT - 200)
font = pygame.font.SysFont(None, 50, True)
msg = " Hovering Message "
hover_surface = font.render(msg, True, pygame.Color("chartreuse"), pygame.Color("firebrick"))
hovering = False
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# update game elements - Get mouse position
mx, my = pygame.mouse.get_pos()
# draw surface - fill background
screen.fill(pygame.Color("grey"))
## draw central rect
screen.fill(pygame.Color("purple"), color_rect)
## display the hovering text if the mouse is over the rectangle
if color_rect.collidepoint((mx, my)):
screen.blit(hover_surface, (mx, my))
# show surface
pygame.display.update()
# limit frames
clock.tick(FPS)
pygame.quit()
您的代码使用了大量的原始几何计算,在长 运行 中使用一些本机 pygame 元素可能更容易。例如,您可以将您的按钮设为不可移动的 Sprites,并将它们放在一个 Sprite 组中,以便于管理它们。
为您的 class 添加另一个文本属性。例如:
class Button():
def __init__(self, x, y, sx, sy, bcolour, fbcolour, font, fontsize, fcolour, text, tiptext):
# [...]
self.tiptextsurface = self.buttonf.render(tiptext, False, (0, 0, 0), (255, 255, 0))
在 Button.showTip
方法中绘制文本,当设置 self.current
时:
class Button():
# [...]
def showTip(self, display):
if self.current:
mouse_pos = pygame.mouse.get_pos()
display.blit(self.tiptextsurface, (mouse_pos[0]+16, mouse_pos[1]))
基于您的代码的最小示例:
我已经简化了 Button
class,但它的行为与您问题中的 class 完全一样。
import pygame
pygame.init()
class Button():
def __init__(self, x, y, sx, sy, bcolour, fbcolour, font, fontsize, fcolour, text, tiptext):
self.rect = pygame.Rect(x, y, sx, sy)
self.bcolour = bcolour
self.fbcolour = fbcolour
self.fcolour = fcolour
self.fontsize = fontsize
self.current = False
self.buttonf = pygame.font.SysFont(font, fontsize)
self.textsurface = self.buttonf.render(text, False, self.fcolour)
self.tiptextsurface = self.buttonf.render(tiptext, False, (0, 0, 0), (255, 255, 0))
def showButton(self, display):
color = self.fbcolour if self.current else self.bcolour
pygame.draw.rect(display, color, self.rect)
display.blit(self.textsurface, self.textsurface.get_rect(center = self.rect.center))
def showTip(self, display):
if self.current:
mouse_pos = pygame.mouse.get_pos()
display.blit(self.tiptextsurface, (mouse_pos[0]+16, mouse_pos[1]))
def focusCheck(self, mousepos, mouseclick):
self.current = self.rect.collidepoint(mousepos)
return mouseclick if self.current else True
screen = pygame.display.set_mode((400, 600))
clock = pygame.time.Clock()
font = pygame.font.Font('freesansbold.ttf', 32)
shopButton = Button(125, 500, 150, 50, "black", "red", "arial", 20, "white", "Shop", "Enter the shop")
done = False
while not done:
clock.tick(60)
for event in pygame.event.get():
if(event.type == pygame.QUIT):
done = True
if event.type == pygame.MOUSEBUTTONDOWN:
mouse_click = True
mouse_pos = pygame.mouse.get_pos()
mouse_click = False
screen2button = shopButton.focusCheck(mouse_pos, mouse_click)
screen.fill((255, 255, 255))
shopButton.showButton(screen)
shopButton.showTip(screen)
pygame.display.update()
pygame.quit()