<p>没有理由在代码中使用线程。它只会让你的代码更难阅读,更难调试,更容易出错。在</p>
<p>通常你想在你的游戏中有一种状态,你用它来确定一个帧中应该发生什么。您可以找到一个基于类的示例<a href="https://stackoverflow.com/q/14700889/142637">here</a>。在</p>
<p>另一种处理此问题的方法(与您的代码有点类似)是使用协同程序。在</p>
<p>查看动画代码,不要调用<code>pygame.display.update()</code>,而是将控件返回主循环。主循环将处理事件、帧限制和绘制,然后将控制权交还给协同程序(它跟踪自己的状态)。在</p>
<p>下面是一个简单的黑客示例:</p>
<pre><code>import pygame
import pygame.freetype
pygame.init()
size = (640, 480)
screen = pygame.display.set_mode(size)
clock = pygame.time.Clock()
def game_state(surf):
rect = pygame.Rect(200, 200, 32, 32)
while True:
events = yield
pressed = pygame.key.get_pressed()
x = 1 if pressed[pygame.K_RIGHT] else -1 if pressed[pygame.K_LEFT] else 0
rect.move_ip(x*5, 0)
pygame.draw.rect(surf, pygame.Color('dodgerblue'), rect)
yield
def title_state(surf):
text = 'Awesome Game'
colors = [[255, 255, 255, 20] for letter in text]
font = pygame.freetype.SysFont(None, 22)
font.origin = True
while True:
for color in colors:
color[3] += 33
if color[3] > 255: color[3] = 0
x = 200
for (letter, c) in zip(text, colors):
bounds = font.get_rect(letter)
font.render_to(surf, (x, 100), letter, c)
x += bounds.width + 1
font.render_to(surf, (180, 150), 'press [space] to start', pygame.Color('grey'))
events = yield
yield
def main():
title = title_state(screen)
game = game_state(screen)
state = title
while True:
events = pygame.event.get()
for e in events:
if e.type == pygame.QUIT:
return
if e.type == pygame.KEYDOWN:
if e.key == pygame.K_ESCAPE:
return
if e.key == pygame.K_SPACE:
state = game if state == title else title
if e.key == pygame.K_f:
if screen.get_flags() & pygame.FULLSCREEN:
pygame.display.set_mode(size)
else:
pygame.display.set_mode(size, pygame.FULLSCREEN)
screen.fill(pygame.Color('grey12'))
next(state)
state.send(events)
pygame.display.update()
clock.tick(60)
if __name__ == '__main__':
main()
</code></pre>
<p>看看主循环是如何干净和简单的,所有的游戏状态都是在协同程序中处理的。代码的标题屏幕部分不关心是否全屏显示或如何切换到全屏,主循环不关心标题屏幕协同程序做什么。我们不需要穿线。在</p>
<p><a href="https://i.stack.imgur.com/pqB2T.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/pqB2T.gif" alt="enter image description here"/></a></p>
<p>实际上,它与我上面链接的基于类的示例没有什么不同,但是使用协同程序可以很容易地实现标题屏幕动画。在</p>
<p>基本上你有一个无止境的循环,你改变一些状态(比如字母的颜色),然后说“现在画这个!”只需调用<code>yield</code>。在</p>