悬停仅适用于第一个按钮
hovering only works on first button
在我的代码中:
class text:
def __init__(self, size, message, color, position, button = False, action = None):
self.size = size
self.message = message
self.color = color
self.position = position
self.text_size = pygame.font.SysFont(None, int(size*displaywidth))
self.Textsurface = self.text_size.render(self.message, True, self.color)
Textrect = self.Textsurface.get_rect()
self.Textrect = Textrect
self.Textwidth = Textrect[2]
self.Textheight = Textrect[3]
self.second_x_pos = Textrect[2] + position[0]
self.second_y_pos = Textrect[3] + position[1]
self.button = button
self.action = action
def display(self):
self.Textrect.topleft = (self.position)
gameWindow.blit(self.Textsurface, self.Textrect)
if self.button == True:
self.Textrect.topleft = (self.position)
gameWindow.blit(self.Textsurface, self.Textrect)
for event in pygame.event.get():
if event.type == pygame.MOUSEMOTION:
if self.position[0] < event.pos[0] < self.second_x_pos and self.position[1] < event.pos[1] < self.second_y_pos:
print("yee")
self.color = white
self.Textsurface = self.text_size.render(self.message, True, self.color)
gameWindow.blit(self.Textsurface, self.Textrect)
else:
self.Textsurface = self.text_size.render(self.message, True, self.color)
if event.type == pygame.MOUSEBUTTONUP :
self.action()
# menu screen
def menu_screen():
global wine
global purple
menu = True
global displaywidth
global displayheight
global gameWindow
global compltely_red
global brown
global red
# Texts
menu_txt = text(0.2,"Timm", red, (displaywidth/2,displayheight/9))
Play_txt = text(0.04, "Play ", wine, (displaywidth/7, displayheight/1.5), True, game_loop)
parallel_button = displaywidth - (displaywidth/7) - Play_txt.Textwidth
Quit_txt = text(0.04, "Quit ", compltely_red, (parallel_button, displayheight/1.5), True, quit_Everything)
#loop
while menu == True:
#the loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit_Everything()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
quit_Everything()
if event.key == pygame.K_f:
displaywidth = 1920
displayheight = 1080
gameWindow = pygame.display.set_mode((displaywidth,displayheight), pygame.FULLSCREEN)
if event.key == pygame.K_g:
displaywidth = 960
displayheight = 960
gameWindow = pygame.display.set_mode((displaywidth,displayheight))
gameWindow.fill(green)
menu_txt.display()
Play_txt.display()
Quit_txt.display()
pygame.display.update()
我调用的第一个按钮("Play" 按钮)运行良好(我还不关心操作,目前对我来说重要的是悬停)。
但是第二个按钮非常有问题(当我颠倒我调用按钮的顺序时,第一个被调用的按钮总是完美的)
第一件事:"frames" 之间没有停顿 - 即检查程序中的事件 - 所以一切都以计算机可以运行的速度完成,使用 100% CPU - 更糟糕的选择。正确的做法是在调用 pygame.display.update
之后等待几十毫秒 - 在那个调用之后立即调用 pygame.time.delay(30)
。
你得到的代码虽然设计不好,但几乎可以工作,但一方面 - 当你调用 pygame.event.get
时,它会获取队列中的所有事件。因此,有一些竞争条件 n,在您的主循环上调用 get
会选择所有事件 - 但由于代码的无暂停性质,第二次调用会选择一些 MOUSEMOTION 事件,在 display
第一个按钮的方法。
当您放置我在上面建议的暂停时,即使是第一个按钮的悬停也应该停止 - 因为它的工作原理只是偶然的,帧之间的暂停将解决这个问题。
现在,您有两个选择 - 如果您想继续检查对象代码中的事件,它们不应该自己调用 pygame.events.get
- 相反,在每个帧上调用一次,并且将结果分配给一个变量——他们将该变量作为参数传递给所有应该处理事件的地方:
在菜单屏幕代码上执行:
while menu: #
#the loop
events = pygame.event.get()
for event in events:
...
gameWindow.fill(green)
menu_txt.display(events)
Play_txt.display(events)
Quit_txt.display(events)
在正文中 class:
def display(self, events):
...
if self.button: # Please, just stop checking truthiness doing "x == True"
self.Textrect.topleft = (self.position)
gameWindow.blit(self.Textsurface, self.Textrect)
for event in events:
if event.type == pygame.MOUSEMOTION:
这应该可以解决您的问题以及您设计中的许多问题。 owever,请注意,如果鼠标实际移动,这些只会突出显示您的文本 - 如果鼠标悬停但没有移动,则不会生成 MOUSEMOTION 事件。因此,您可能会检查鼠标位置本身是否在按钮矩形内,而不是检查事件 - 您直接获取鼠标位置,而不是依赖于事件。此外,在使用它时,您可能更喜欢使用 Pygame 的矩形计算函数,而不是令人不快的 self.position[0] < event.pos[0] < self.second_x_pos and self.position[1] < event.pos[1] < self.second_y_pos
表达式。
在 __init__
:
self.rect = pygame.Rect(self.pos + tuple(Textrect[2:])
并在 if
上检查指针是否在矩形内:
def display(self, events):
if self.button:
if self.rect.contains(pygame.mouse.get_pos() + (1,1)):
print("yee")
...
在我的代码中:
class text:
def __init__(self, size, message, color, position, button = False, action = None):
self.size = size
self.message = message
self.color = color
self.position = position
self.text_size = pygame.font.SysFont(None, int(size*displaywidth))
self.Textsurface = self.text_size.render(self.message, True, self.color)
Textrect = self.Textsurface.get_rect()
self.Textrect = Textrect
self.Textwidth = Textrect[2]
self.Textheight = Textrect[3]
self.second_x_pos = Textrect[2] + position[0]
self.second_y_pos = Textrect[3] + position[1]
self.button = button
self.action = action
def display(self):
self.Textrect.topleft = (self.position)
gameWindow.blit(self.Textsurface, self.Textrect)
if self.button == True:
self.Textrect.topleft = (self.position)
gameWindow.blit(self.Textsurface, self.Textrect)
for event in pygame.event.get():
if event.type == pygame.MOUSEMOTION:
if self.position[0] < event.pos[0] < self.second_x_pos and self.position[1] < event.pos[1] < self.second_y_pos:
print("yee")
self.color = white
self.Textsurface = self.text_size.render(self.message, True, self.color)
gameWindow.blit(self.Textsurface, self.Textrect)
else:
self.Textsurface = self.text_size.render(self.message, True, self.color)
if event.type == pygame.MOUSEBUTTONUP :
self.action()
# menu screen
def menu_screen():
global wine
global purple
menu = True
global displaywidth
global displayheight
global gameWindow
global compltely_red
global brown
global red
# Texts
menu_txt = text(0.2,"Timm", red, (displaywidth/2,displayheight/9))
Play_txt = text(0.04, "Play ", wine, (displaywidth/7, displayheight/1.5), True, game_loop)
parallel_button = displaywidth - (displaywidth/7) - Play_txt.Textwidth
Quit_txt = text(0.04, "Quit ", compltely_red, (parallel_button, displayheight/1.5), True, quit_Everything)
#loop
while menu == True:
#the loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit_Everything()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
quit_Everything()
if event.key == pygame.K_f:
displaywidth = 1920
displayheight = 1080
gameWindow = pygame.display.set_mode((displaywidth,displayheight), pygame.FULLSCREEN)
if event.key == pygame.K_g:
displaywidth = 960
displayheight = 960
gameWindow = pygame.display.set_mode((displaywidth,displayheight))
gameWindow.fill(green)
menu_txt.display()
Play_txt.display()
Quit_txt.display()
pygame.display.update()
我调用的第一个按钮("Play" 按钮)运行良好(我还不关心操作,目前对我来说重要的是悬停)。 但是第二个按钮非常有问题(当我颠倒我调用按钮的顺序时,第一个被调用的按钮总是完美的)
第一件事:"frames" 之间没有停顿 - 即检查程序中的事件 - 所以一切都以计算机可以运行的速度完成,使用 100% CPU - 更糟糕的选择。正确的做法是在调用 pygame.display.update
之后等待几十毫秒 - 在那个调用之后立即调用 pygame.time.delay(30)
。
你得到的代码虽然设计不好,但几乎可以工作,但一方面 - 当你调用 pygame.event.get
时,它会获取队列中的所有事件。因此,有一些竞争条件 n,在您的主循环上调用 get
会选择所有事件 - 但由于代码的无暂停性质,第二次调用会选择一些 MOUSEMOTION 事件,在 display
第一个按钮的方法。
当您放置我在上面建议的暂停时,即使是第一个按钮的悬停也应该停止 - 因为它的工作原理只是偶然的,帧之间的暂停将解决这个问题。
现在,您有两个选择 - 如果您想继续检查对象代码中的事件,它们不应该自己调用 pygame.events.get
- 相反,在每个帧上调用一次,并且将结果分配给一个变量——他们将该变量作为参数传递给所有应该处理事件的地方:
在菜单屏幕代码上执行:
while menu: #
#the loop
events = pygame.event.get()
for event in events:
...
gameWindow.fill(green)
menu_txt.display(events)
Play_txt.display(events)
Quit_txt.display(events)
在正文中 class:
def display(self, events):
...
if self.button: # Please, just stop checking truthiness doing "x == True"
self.Textrect.topleft = (self.position)
gameWindow.blit(self.Textsurface, self.Textrect)
for event in events:
if event.type == pygame.MOUSEMOTION:
这应该可以解决您的问题以及您设计中的许多问题。 owever,请注意,如果鼠标实际移动,这些只会突出显示您的文本 - 如果鼠标悬停但没有移动,则不会生成 MOUSEMOTION 事件。因此,您可能会检查鼠标位置本身是否在按钮矩形内,而不是检查事件 - 您直接获取鼠标位置,而不是依赖于事件。此外,在使用它时,您可能更喜欢使用 Pygame 的矩形计算函数,而不是令人不快的 self.position[0] < event.pos[0] < self.second_x_pos and self.position[1] < event.pos[1] < self.second_y_pos
表达式。
在 __init__
:
self.rect = pygame.Rect(self.pos + tuple(Textrect[2:])
并在 if
上检查指针是否在矩形内:
def display(self, events):
if self.button:
if self.rect.contains(pygame.mouse.get_pos() + (1,1)):
print("yee")
...