人们如何有效地处理重复的事件检查 (python/pygame)?
How do people efficiently handle repetitive event checks (python/pygame)?
这更像是一个好奇的问题,因为我回去并设法做了我想做的事情。标题原本是 'Checking if an ordered tuple is in a tuple of ranges?'
到目前为止,我一直在使用此代码检查鼠标点击 -
pos = pygame.mouse.get_pos()
if pos[0] > X and pos[0] < X2 and pos[1] > Y and pos[1] < Y2:
#Do this
#Separate function with same XY's
if pos[0] > X and pos[0] < X2 and pos[1] > Y and pos[1] < Y2:
#Do something else - could be used for mouse hover rather than click.
我想知道其他人是如何进行按钮检测的,因为有时需要不止一次检查(例如在单独的函数中)。有时我会触发一个外部函数、布尔值或计时器,或者类似的东西。我已经在下面的例子中做到了。但这也可能变得混乱,我觉得必须有更简单的方法。
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
gp = game.pos
#Initial gbh declaration
gbh = game.button_health = range(391, 527), range(179, 253)
if gp[0] in gbh[0] and gp[1] in gbh[1]:
player.skillpoints -= 1
player.health += 10
player.healthmax += 10
#Separate func.
gp = game.pos
gbh = game.button_health
if gp[0] in gbh[0] and gp[1] in gbh[1]:
blit(font.render(str(Z), True, BLACK), (X, Y))
如果你有重复的代码,那么你可以把它放到一个函数中,然后在代码所在的地方调用它。这使得以后修改代码变得更容易,因为您只需要在一个地方更改它。测试代码也更容易。
举个例子(我也加了一个Google style docstring):
def collided(pos, X, X2, Y, Y2):
"""Check if a point `pos` collides with an area.
Args:
pos (tuple): The point.
X (int, float): The left coordinate of the area.
etc.
Returns:
bool: True if it collides, otherwise False.
"""
return pos[0] > X and pos[0] < X2 and pos[1] > Y and pos[1] < Y2
# Call the function and pass the needed arguments.
if collided(pg.mouse.get_pos(), X, X2, Y, Y2):
print('collision')
由于你的问题被标记为 performance
,最好从一句名言开始:
"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%" (D. Knuth, "Structured Programming with go to Statements", emphasize mine)
您确定这会对您的应用程序的全局性能产生影响吗?如果 4 次比较产生影响,我会 非常 感到惊讶。所以我们假设这不是性能问题。
首先注意在Python中可以这样写:
if X < pos[0] < X2 and Y < pos[1] < Y2:
....
但还有更重要的一点:弄清楚你正在测试的内容。你将如何说清楚?简单地命名它:
if pos[0] > X and pos[0] < X2 and pos[1] > Y and pos[1] < Y2:
# Do this
变成:
if area_contains(X, X2, Y, Y2, pos):
# Do this
或自定义 class:
area = Area(X, X2, Y, Y2)
if area.contains(pos):
# Do this
为了清楚起见,即使您只有一项测试,您也应该这样做。函数不仅用于减少重复代码(DRY:不要重复自己),还用于提高可读性。看看这个:
player.skillpoints -= 1
player.health += 10
player.healthmax += 10
为什么不呢:
player.increase_health()
?
不要只将对象用作结构:它们为您提供了一种方便的方式来表达您正在做的事情,而无需透露实现细节。现在,您可以更改 increase_health
的含义,而无需查找导致它的所有事件。
这更像是一个好奇的问题,因为我回去并设法做了我想做的事情。标题原本是 'Checking if an ordered tuple is in a tuple of ranges?'
到目前为止,我一直在使用此代码检查鼠标点击 -
pos = pygame.mouse.get_pos()
if pos[0] > X and pos[0] < X2 and pos[1] > Y and pos[1] < Y2:
#Do this
#Separate function with same XY's
if pos[0] > X and pos[0] < X2 and pos[1] > Y and pos[1] < Y2:
#Do something else - could be used for mouse hover rather than click.
我想知道其他人是如何进行按钮检测的,因为有时需要不止一次检查(例如在单独的函数中)。有时我会触发一个外部函数、布尔值或计时器,或者类似的东西。我已经在下面的例子中做到了。但这也可能变得混乱,我觉得必须有更简单的方法。
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
gp = game.pos
#Initial gbh declaration
gbh = game.button_health = range(391, 527), range(179, 253)
if gp[0] in gbh[0] and gp[1] in gbh[1]:
player.skillpoints -= 1
player.health += 10
player.healthmax += 10
#Separate func.
gp = game.pos
gbh = game.button_health
if gp[0] in gbh[0] and gp[1] in gbh[1]:
blit(font.render(str(Z), True, BLACK), (X, Y))
如果你有重复的代码,那么你可以把它放到一个函数中,然后在代码所在的地方调用它。这使得以后修改代码变得更容易,因为您只需要在一个地方更改它。测试代码也更容易。
举个例子(我也加了一个Google style docstring):
def collided(pos, X, X2, Y, Y2):
"""Check if a point `pos` collides with an area.
Args:
pos (tuple): The point.
X (int, float): The left coordinate of the area.
etc.
Returns:
bool: True if it collides, otherwise False.
"""
return pos[0] > X and pos[0] < X2 and pos[1] > Y and pos[1] < Y2
# Call the function and pass the needed arguments.
if collided(pg.mouse.get_pos(), X, X2, Y, Y2):
print('collision')
由于你的问题被标记为 performance
,最好从一句名言开始:
"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%" (D. Knuth, "Structured Programming with go to Statements", emphasize mine)
您确定这会对您的应用程序的全局性能产生影响吗?如果 4 次比较产生影响,我会 非常 感到惊讶。所以我们假设这不是性能问题。
首先注意在Python中可以这样写:
if X < pos[0] < X2 and Y < pos[1] < Y2:
....
但还有更重要的一点:弄清楚你正在测试的内容。你将如何说清楚?简单地命名它:
if pos[0] > X and pos[0] < X2 and pos[1] > Y and pos[1] < Y2:
# Do this
变成:
if area_contains(X, X2, Y, Y2, pos):
# Do this
或自定义 class:
area = Area(X, X2, Y, Y2)
if area.contains(pos):
# Do this
为了清楚起见,即使您只有一项测试,您也应该这样做。函数不仅用于减少重复代码(DRY:不要重复自己),还用于提高可读性。看看这个:
player.skillpoints -= 1
player.health += 10
player.healthmax += 10
为什么不呢:
player.increase_health()
?
不要只将对象用作结构:它们为您提供了一种方便的方式来表达您正在做的事情,而无需透露实现细节。现在,您可以更改 increase_health
的含义,而无需查找导致它的所有事件。