所以我有一个函数(如下),我想每 2 秒更改一次变量。目前,该函数每 2 秒更改一次变量 (goblinx)。问题是 time.wait 导致所有函数暂停 2 秒。我怎么可能只有函数 movegoblin() 暂停。
def movegoblin():
global goblinx
global gobliny
x = 1
if x == 1:
goblinx += 32
pygame.time.wait(200)
去这里的方法是改进你的地精?(和其他角色)在你的程序中从函数到适当的类的处理,这样它们就可以有内部状态。
每个此类它们都可以具有在每个游戏帧更新的变量,并且当计数达到一个值时触发一个动作。
这个解决方案比仅仅为了计时而添加并发线程更干净,并且正确地完成,可以导致应用程序设计,这将是开发、扩展和维护的一种幸福。
您可以采用的样式的简短示例,保留代码中的功能。(请注意,您可以使用 pygame.sprite.Sprite 类为每个对象组自动调用“更新”方法 - 我将在下面从头开始)
帧延迟 = 20
class Goblin(object):
def __init__(self):
self.x = 1 #or whatever
self.y = 1 #or whatever
self.movement_count = 0
self.move_at_each = 10
def move(self):
self.movement_count += 1
if self.movement_count < self.move_at_each:
return
self.movement_count = 0
self.x += 32
在你的主循环中,你实例化一个妖精,做:
goblin = Goblin()
, 在进入 while 循环之前,并 goblin.move()
在每一帧调用。通过这种方式,您可以拥有一个适当的地精类,这将允许您在游戏中拥有多个“地精” - 而您示例中的代码将要求您对每个角色进行硬编码。您只需在游戏的每一帧调用“goblin.move”方法。上面的示例被调整为每 10 帧移动一次,但您可以更改它(并且可以为您实例化的每个单独的地精更改它)。
正如我所说,pygame 已经提供了“Sprite”和“sprite groups”类作为这种机制的框架,但是在一些较小的游戏中滚动你自己的类将帮助你更好地了解需求以及 pygame sprites 已经提供的内容,因此您可以在以后的项目(或该项目的后期)中使用它们
最简单的答案:
每帧在你的地精上调用一个 .update() 函数。如果时间流逝 >= 200 毫秒,则移动他。否则什么也不做。
class Unit():
def __init__(self):
self.update_delay = 200
self.last_update = pygame.time.get_ticks()
def update(self):
# call once per game update.
now = pygame.time.get_ticks()
if now - self.last_update >= self.update_delay:
self.last_update = now
# update AI , pathfind , etc.
self.x += 30
我认为大多数人首先会想到的答案是:“你想错了!” ——如果你遵循传统的游戏开发方法,这实际上是正确的;jsbueno 和猴子向您展示了您通常如何去那里。
我只想指出一个 python 项目,它试图以解决问题的方式给出解决方案。主张是:现实世界是并发的,因此您应该以并发的方式对其进行建模(您的直观方法是并发的这一事实支持这一点)。
问题是,在问题上使用真正的多线程方法肯定会给您带来比它解决的问题更多的问题,因为您必须考虑竞争条件等(因此在 sajatack 的答案中使用互斥锁)。此外,如果您的游戏中有数百个精灵/对象,则数百个线程的开销(这不是一个很高的数字,如果您想开始思考大的话,请考虑那里的数万个)对于处理它的糟糕计算机来说很可能是矫枉过正的.
这就是为什么有些人开始了一个名为stackless python的项目。他们想提供一种工具,让您无需多线程即可以并发方式编程!有了它,您可以按照您的建议进行编程,让一个功能等待,而其他功能继续运行。他们称为微线程背后的概念还有一篇很好的文章介绍了编程中的并发思维。您可能想查看该项目,但这可能会给您带来几个问题:
import _thread
_thread.start_new_thread(movegoblin, ())
或者如果你喜欢
import threading
threading.Thread(target=movegoblin).start()
带锁:
mutex = _thread.allocate_lock()
def movegoblin():
global goblinx
global gobliny
x = 1
if x == 1:
mutex.acquire()
goblinx += 32
pygame.time.wait(200)
mutex.release()