我有一个简单的动画来处理我绘制矩形的位置,当我点击表面时,矩形向左滑动并等待2秒,然后向右滑动重绘它,但如果我减少或移动窗口试一试窗口在等待时刻冻结。
以下是代码:
import sys, pygame
from pygame.locals import *
pygame.init()
FPS = 30
BGCOLOR = (255, 255, 255)
RECTCOLOR = (10, 0, 199)
DS = pygame.display.set_mode( (200,200) )
CLOCK = pygame.time.Clock()
pygame.display.set_caption('Demo')
def main():
DS.fill(BGCOLOR)
pygame.draw.rect(DS, RECTCOLOR, (50, 50, 100, 100))
pygame.display.update()
while 1:
ev = pygame.event.wait()
if ev.type == QUIT:
pygame.quit()
sys.exit()
elif ev.type == MOUSEBUTTONUP:
animation()
def animation():
pygame.event.set_blocked(MOUSEBUTTONUP)
for x in range(10, 101, 10):
pygame.draw.rect(DS, BGCOLOR, (150 - x,50,x,100))
pygame.display.update()
CLOCK.tick(FPS)
pygame.time.wait(2000) # 2 seconds
for x in range(10, 101, 10):
pygame.draw.rect(DS, RECTCOLOR, (50,50,x,100))
pygame.display.update()
CLOCK.tick(FPS)
pygame.event.set_allowed(MOUSEBUTTONUP)
if __name__ == '__main__':
main()
为什么我们会出现这种行为?也许系统不会在第二个for循环中的暂停时刻和刻度之间同步
PS:我在Windows 7上,对不起我的英语,这不是我的母语
答案 0 :(得分:1)
两件事:
当您运行这样的循环时:
for x in range(10, 101, 10):
pygame.draw.rect(DS, BGCOLOR, (150 - x,50,x,100))
pygame.display.update()
你绘制动画,但是pygame没有机会处理它从你的操作系统获得的消息。为避免这种情况,您应该在循环内调用pygame.event.pump()
或pygame.event.get()
。
来自docs:
<强> pygame.event.pump()强>
对于游戏的每一帧,您需要对事件队列进行某种调用。这可确保您的程序可以在内部与操作系统的其余部分进行交互。如果您没有在游戏中使用其他事件函数,则应调用pygame.event.pump()以允许pygame处理内部操作。
如果程序通过其他pygame.event函数一致地处理队列中的事件,则不需要此函数。
必须在事件队列内部处理重要事项。主窗口可能需要重新绘制或响应系统。如果您未能长时间调用事件队列,系统可能会决定您的程序已被锁定。
此外,在移动窗户时,您的游戏将会冻结。这是SDL的一个已知限制(记住pygame只是SDL的一个薄包装)并且由Windows消息循环引起:当你移动窗口或调整窗口大小时,windows使用模态循环,这将阻止游戏运行的线程
答案 1 :(得分:1)
我建议您只使用一个循环并使用变量或用户事件来跟踪游戏状态。
示例:
game_state = 0
def main():
global game_state
rectangle_ticks = 0
while 1:
events = pygame.event.get() # Get all pending events
for ev in events:
# Process events
if ev.type == QUIT:
pygame.quit()
sys.exit()
elif ev.type == MOUSEBUTTONUP:
game_state = 1
pygame.time.set_timer(pygame.time.set_timer(pygame.USEREVENT + 1, 1000)
elif ev.type == pygame.USEREVENT + 1:
pygame.time.set_timer(pygame.time.set_timer(pygame.USEREVENT + 1, 0)
game_state = 2
# Clear screen
DS.fill(BGCOLOR)
# Draw game state
pygame.draw.rect(DS, RECTCOLOR, (50, 50, 100, 100))
animation()
# Update screen
pygame.display.flip()
CLOCK.tick(FPS)
def animation():
if game_state == 1:
for x in range(10, 101, 10):
pygame.draw.rect(DS, BGCOLOR, (150 - x,50,x,100))
if game_state == 2:
for x in range(10, 101, 10):
pygame.draw.rect(DS, RECTCOLOR, (50,50,x,100))
在每个刻度中绘制整个屏幕可能看起来很奇怪,但这是在pygame中工作的常用方法,以便摆脱不想继续绘制的旧对象。
答案 2 :(得分:1)