pygame 中的新循环的变量值未正确更新
Values of variables don't update properly for new loop in pygame
使用 pygame 和 python 3.7,我创建了一个游戏,其中中心 (250, 250) 的图像可以在屏幕上拖动并与半径碰撞,其中如果发生中断,下一个循环中的下一个图像会在准确的中心产生,第一个图像也位于该中心。尽管游戏按照我预期的方式运行,但原则上,它在快速鼠标速度下表现得很奇怪。在我的最小示例代码中,彩色圆圈应该在每个 while 循环中重新出现在确切的中心,但是,它们以某种方式无法正确更新,因此大部分时间都不会重新出现在屏幕中心(它们仅当我很早/适时释放鼠标按钮时才这样做)。我在 windows 和 mac 上测试了游戏并注意到在我的 mac 上,"lag" 似乎更糟。如果有人知道我该如何解决这个问题,我将非常感激。此外,游戏开始滞后并立即跳到下一个循环以实现真正快速的鼠标移动,我通过更改外接鼠标的速度来解决这个问题。 pygame 中鼠标移动过快是否有固有的修复方法?感谢所有建议,也许还有对我的代码想法的其他改进。
import pygame
import time
from time import sleep
import math
pygame.init()
gameDisplay = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()
background_surface = pygame.Surface((500, 500))
background_surface.fill((255, 255, 255))
colors = [(0,0,0), (253, 45, 0), (249, 253, 0), (32, 201, 5), (0, 210, 235)]
for color in colors:
done = False
a, b = 250, 250
u, v = 250, 250
while not done:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEMOTION:
if event.buttons[0]:
a += event.rel[0]
b += event.rel[1]
rect = pygame.Rect(u, v, 0.001, 0.001)
radius = 200
corners = [rect.bottomleft, rect.bottomright, rect.topleft, rect.topright]
dist = [math.sqrt((p[0] - a) ** 2 + (p[1] - b) ** 2) for p in corners]
p_out = [i for i, d in enumerate(dist) if d > radius]
if any(p_out):
break
gameDisplay.blit(background_surface, (0, 0))
pygame.draw.circle(gameDisplay, color, (a,b), 50, 0)
pygame.draw.circle(gameDisplay, (0,0,0), (250,250), 200, 2)
pygame.display.flip()
sleep(0.7)
pygame.quit()
quit()
[...] they somehow don't update properly and therefore reappear not at the center of the screen, most of the time (they only do when I release the mouse-button really early / well-timed) [...]
当然,请调查您的代码。您的代码中发生的第一件事是 a
和 b
被修改:
while not done:
# [...]
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEMOTION:
if event.buttons[0]:
a += event.rel[0]
b += event.rel[1]
如果 pygame.MOUSEMOTION
事件在队列中,则在绘制圆之前处理它。所以修改了圆的位置,不出现在中心
请注意,事件不反映鼠标的当前状态。它是一个通知,当它发生时存储在队列中,但事件处理可能会在以后完成。你实际上做的是处理一个事件,这个事件可能发生在过去。
在每个循环开始时使用状态 dragging
,即 False
。设置按下按钮时的状态(pygame.MOUSEBUTTONDOWN
事件),释放按钮时重置状态(pygame.MOUSEBUTTONUP
事件):
for color in colors:
# [...]
dragging = False
while not done:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
dragging = True
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
dragging = False
elif event.type == pygame.MOUSEMOTION:
if dragging:
a += event.rel[0]
b += event.rel[1]
# [...]
使用 pygame 和 python 3.7,我创建了一个游戏,其中中心 (250, 250) 的图像可以在屏幕上拖动并与半径碰撞,其中如果发生中断,下一个循环中的下一个图像会在准确的中心产生,第一个图像也位于该中心。尽管游戏按照我预期的方式运行,但原则上,它在快速鼠标速度下表现得很奇怪。在我的最小示例代码中,彩色圆圈应该在每个 while 循环中重新出现在确切的中心,但是,它们以某种方式无法正确更新,因此大部分时间都不会重新出现在屏幕中心(它们仅当我很早/适时释放鼠标按钮时才这样做)。我在 windows 和 mac 上测试了游戏并注意到在我的 mac 上,"lag" 似乎更糟。如果有人知道我该如何解决这个问题,我将非常感激。此外,游戏开始滞后并立即跳到下一个循环以实现真正快速的鼠标移动,我通过更改外接鼠标的速度来解决这个问题。 pygame 中鼠标移动过快是否有固有的修复方法?感谢所有建议,也许还有对我的代码想法的其他改进。
import pygame
import time
from time import sleep
import math
pygame.init()
gameDisplay = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()
background_surface = pygame.Surface((500, 500))
background_surface.fill((255, 255, 255))
colors = [(0,0,0), (253, 45, 0), (249, 253, 0), (32, 201, 5), (0, 210, 235)]
for color in colors:
done = False
a, b = 250, 250
u, v = 250, 250
while not done:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEMOTION:
if event.buttons[0]:
a += event.rel[0]
b += event.rel[1]
rect = pygame.Rect(u, v, 0.001, 0.001)
radius = 200
corners = [rect.bottomleft, rect.bottomright, rect.topleft, rect.topright]
dist = [math.sqrt((p[0] - a) ** 2 + (p[1] - b) ** 2) for p in corners]
p_out = [i for i, d in enumerate(dist) if d > radius]
if any(p_out):
break
gameDisplay.blit(background_surface, (0, 0))
pygame.draw.circle(gameDisplay, color, (a,b), 50, 0)
pygame.draw.circle(gameDisplay, (0,0,0), (250,250), 200, 2)
pygame.display.flip()
sleep(0.7)
pygame.quit()
quit()
[...] they somehow don't update properly and therefore reappear not at the center of the screen, most of the time (they only do when I release the mouse-button really early / well-timed) [...]
当然,请调查您的代码。您的代码中发生的第一件事是 a
和 b
被修改:
while not done: # [...] for event in pygame.event.get(): if event.type == pygame.QUIT: done = True elif event.type == pygame.MOUSEMOTION: if event.buttons[0]: a += event.rel[0] b += event.rel[1]
如果 pygame.MOUSEMOTION
事件在队列中,则在绘制圆之前处理它。所以修改了圆的位置,不出现在中心
请注意,事件不反映鼠标的当前状态。它是一个通知,当它发生时存储在队列中,但事件处理可能会在以后完成。你实际上做的是处理一个事件,这个事件可能发生在过去。
在每个循环开始时使用状态 dragging
,即 False
。设置按下按钮时的状态(pygame.MOUSEBUTTONDOWN
事件),释放按钮时重置状态(pygame.MOUSEBUTTONUP
事件):
for color in colors:
# [...]
dragging = False
while not done:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
dragging = True
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
dragging = False
elif event.type == pygame.MOUSEMOTION:
if dragging:
a += event.rel[0]
b += event.rel[1]
# [...]