我正在设计一款Python游戏,并想知道如何制作一个可以在游戏中运行的高效计时器。
注意:我正在使用Pygame。
我目前有一个像这样的计时器:
import time
seconds = 60
def start_timer():
global seconds
while seconds > 0:
print seconds
seconds -= 1
time.sleep(1)
然而,当我在主游戏功能中运行时,我的游戏因timer.sleep
而挂起。
def main(self):
Timer.start_timer()
我很确定我的问题与不使用线程有关,尽管我并不是100%肯定。有人可以帮我解释一下正确的解决方案是什么吗?
答案 0 :(得分:0)
如果您正在使用PyGame或其他图形库,并围绕事件循环或帧速率循环构建游戏,则需要使用该库附带的功能。如果您有一个事件循环,您可以要求它安排一个事件在60秒内触发。如果你有一个帧速率循环,你可以做同样的事情,或者需要检查一次/帧的剩余时间。
但如果你不这样做,那么是的,线程就是答案。
对于简单的计时器,最简单的解决方案是Timer
类。但是,这不会自动执行重复计时器,因此您必须手动添加它。例如,您可以启动1秒计时器,并在计时器到期时启动另一个1秒计时器:
def start_timer():
global seconds
if seconds > 0:
print seconds
seconds -= 1
threading.Timer(1, start_timer).start()
seconds = 60
threading.Timer(1, start_timer).start()
但是,使用知道如何为您重复的计时器通常会容易得多。您可以自己构建一个(请注意threading
文档包含指向source的链接,并且不难发现如何添加逻辑,使其每interval
秒触发一次{ {1}}次,而不仅仅是一次)。或者你可以go search PyPI找到几十个已经为你实现过的人。
还要记住,一旦使用线程,就必须处理线程问题。如果您使用的是GUI库,它们通常不会让您从后台线程调用GUI方法。如果您正在访问在两个线程之间共享的变量,则通常需要Lock
或其他同步对象来保护它。等等。
答案 1 :(得分:0)
如果您正在使用PyGame,它应该使用自己的time functionality。
如果您正在使用事件循环或混合设计,您可以在pygame.event.get()
或类似地方循环,并调用"事件处理程序"对于鼠标单击或按键等不同事件,您可以使用set_timer
创建每秒触发的事件。例如:
TIMER1_EVENT = pygame.USEREVENT + 1
def start_timer1():
global seconds
seconds = 60
pygame.time.set_timer(TIMER1_EVENT, 1000)
def on_timer1():
global seconds
print seconds
seconds -= 1
if seconds < 0:
pygame.time.set_timer(TIMER1_EVENT, 0)
# elsewhere, inside your main event loop
elif event.type == TIMER1_EVENT:
on_timer1()
每个函数的文档中都链接了非常简单的示例程序;如果你看一下set_timer
的例子,你会看到它的使用是多么容易。
如果您使用纯帧循环,那么您可能已经调用了Clock.tick
或类似的东西,并且您将不得不使用其中的返回值来计算自上次以来的毫秒数,并确定您是否通过了另一个整数秒,以及当您通过0时。