Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python游戏计时器(线程?)_Python_Multithreading_Timer_Pygame - Fatal编程技术网

Python游戏计时器(线程?)

Python游戏计时器(线程?),python,multithreading,timer,pygame,Python,Multithreading,Timer,Pygame,我正在用Python设计一个游戏,我想知道如何制作一个高效的计时器,它可以在我的游戏中运行 注意:我正在使用Pygame。 我目前有这样一个计时器: import time seconds = 60 def start_timer(): global seconds while seconds > 0: print seconds seconds -= 1 time.sleep(1) 但是,当在我的主游戏功能中运行时,由

我正在用Python设计一个游戏,我想知道如何制作一个高效的计时器,它可以在我的游戏中运行

注意:我正在使用Pygame。

我目前有这样一个计时器:

import time

seconds = 60

def start_timer():
    global seconds
    while seconds > 0:
        print seconds
        seconds -= 1
        time.sleep(1)
但是,当在我的主游戏功能中运行时,由于
定时器。sleep
,我的游戏挂起

def main(self):
    Timer.start_timer()

我很确定我的问题与不使用线程有关,尽管我不是100%确定。有人能帮我解释一下什么是正确的解决方案吗?

如果您正在使用PyGame或其他图形库,并且已经围绕事件循环或帧速率循环构建了游戏,那么您需要使用该库附带的函数。如果你有一个事件循环,你可以要求它安排一个事件在60秒内触发。如果你有一个帧速率循环,你可能可以做同样的事情,或者需要检查剩余时间一次/帧

但是如果你不这样做,那么是的,线程就是答案

对于简单计时器,最简单的解决方案是类。但是,这不会自动执行重复计时器,因此必须手动添加。例如,您可以启动一个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()
然而,使用一个知道如何为你重复的计时器通常要容易得多。您可以自己构建一个(请注意,
线程化
文档包含到的链接,不难理解如何添加逻辑,使其每隔
间隔
秒触发一次,而不是只触发一次)。或者你可以找到几十个已经为你实现了这一点的人


还要记住,一旦使用线程,就必须处理线程问题。如果您使用的是GUI库,它们通常不允许您从后台线程调用GUI方法。如果要访问在两个线程之间共享的变量,通常需要一个或其他同步对象来保护它。等等。

如果您使用的是PyGame,它有自己的功能,您应该使用它

如果您使用的是事件循环或混合设计,其中您循环使用
pygame.event.get()
或类似的方法,并为不同的事件(如鼠标单击或按下键)调用“事件处理程序”,则可以使用创建每秒触发的事件。例如:

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()
TIMER1\u EVENT=pygame.USEREVENT+1
def start_timer1():
全局秒数
秒=60
pygame.time.set_定时器(TIMER1_事件,1000)
def on_timer1():
全局秒数
打印秒数
秒-=1
如果秒数小于0:
pygame.time.set_计时器(TIMER1_事件,0)
#在其他地方,在主事件循环中
elif event.type==计时器1\u事件:
关于_timer1()
每个功能的文档中都链接有非常简单的示例程序;如果你看一下
set\u timer
的例子,你会发现它是多么容易使用


如果您使用的是纯帧循环,那么您可能已经调用了,您必须使用它的返回值来倒数自上次以来的毫秒数,并确定您是否已通过另一个整数秒数以及何时通过0。

这是一个使用类似PyGame的图形游戏吗?如果是这样,可能有比线程更好的答案。但是线程仍然可以工作。是的,这是一个使用PyGame的游戏!然而,我使用的是帧速率循环;您的代码似乎稍微起作用。我该如何做一个计时器,它的行为方式与我的上面相同?我想每1秒递减一次,这似乎启动了两个计时器,而我只想要一个。Thanks@test:这只启动一个计时器,但该计时器在1秒后过期,因此您启动第二个计时器,该计时器在1秒后过期,因此您启动第三个计时器,依此类推,直到第60个计时器过期,并且您没有点击
if
,也没有启动第61个计时器。这就是为什么内置的
计时器使用起来很笨拙,以及为什么我建议使用另一种替代方法。这是我的主循环的粘贴箱:我相信它是一个帧循环,因为我有
时钟。勾选
。你能用我的代码给我举个例子吗?我对Pygame还相当陌生。谢谢@测试:您仍然有一个围绕
pygame.event.get()
的循环,这意味着您仍然可以使用
pygame.time.set\u timer()
。如果根本没有事件循环,则只需要手动计数代码。在代码中,只需在第61行之后添加此
elif
。当然,在任何情况下,无论你想启动计时器,都要添加对
start\u timer1()
的调用。嗯,当我添加
elif:on\u timer1()
时,计时器永远不会启动,当我删除
elif
时,它似乎只是随机运行,而不是每秒运行一次。我很抱歉没有理解这一点。正如我所说,我是Pygame的新手。