将pygame与twisted结合的难点在于主循环的控制问题。通常当想要将任何类型的UI(如GTK、Tkinter等)主循环与Twisted相结合时会遇到这个问题,而PyGame也不例外。
我的建议是,既然网络延迟很重要,而且twisted具有非常好的调度框架,那么就让twisted反应器运行并掌控主循环,然后使用LoopingCall可以让你处理pygame事件。
最基本的做法是:
from twisted.internet.task import LoopingCall
DESIRED_FPS = 30.0 # 30 frames per second
def game_tick():
events = pygame.events.get()
for event in events:
# Process input events
redraw()
# Set up a looping call every 1/30th of a second to run your game tick
tick = LoopingCall(game_tick)
tick.start(1.0 / DESIRED_FPS)
# Set up anything else twisted here, like listening sockets
reactor.run() # Omit this if this is a tap/tac file
尽管这一看起来很简单,但却存在风险。如果你在游戏的处理逻辑中花费大量时间,则有可能会使twisted反应器饥饿,导致无法处理事件。如果需要计时事件,请不要进行阻塞,而是利用twisted工具,如reactor.callLater
。你能够避免阻塞的越多,你的应用程序就越响应。编程twisted涉及到的内容较多,需要一定的时间来适应这种异步或非阻塞库的编程思想。
更完整的示例,请查看“gam3”,这是一个与twisted交互的游戏库(包括仿真事件的世界时钟)和由twisted开发人员制作的示例游戏,展示了如何集成twisted和pygame。