我听说协同程序是构建游戏的好方法(例如,PEP 342:“协同程序是表达许多算法的自然方式,例如模拟,游戏......”)但我是我很难理解这将如何实现。
我从这个article看到,协同程序可以表示状态机中的状态,它们使用调度程序相互转换,但我不清楚这是如何适用于游戏状态正在改变的游戏来自多个玩家。
是否有使用协同程序编写的游戏的简单示例?或者有人可以提供如何完成的草图吗?
答案 0 :(得分:9)
协同程序允许使用协作式多任务处理创建大量非常轻量级的“微线程”(即,微线程会故意暂停以允许其他微线程运行)。阅读Dave Beazley关于这个主题的article。
现在,很明显这样的微线程如何对游戏编程有用。考虑一个实时战略游戏,你有几十个单位 - 每个单位都有自己的想法。对于每个单元的AI来说,在模拟的多任务环境中作为这样的微线程运行可能是一个方便的抽象。这只是一个例子,我相信还有更多。
Google上的“coroutine游戏编程”搜索似乎带来了有趣的结果。
答案 1 :(得分:8)
最常见的协同程序案例是旧的图形点和点击冒险游戏,它们用于编写游戏中的过场动画和其他动画序列。一个简单的代码示例如下所示:
# script_file.scr
bob.walkto(jane)
bob.lookat(jane)
bob.say("How are you?")
wait(2)
jane.say("Fine")
...
这整个序列不能写成普通代码,因为你想看到bob在你bob.walkto(jane)
之后执行他的步行动画而不是直接跳到下一行。然而,对于你来说,漫步动画需要将控制权交还给游戏引擎,这就是协同程序发挥作用的地方。
整个序列作为协程执行,这意味着您可以根据需要暂停和恢复它。像bob.walkto(jane)
之类的命令因此告诉引擎侧bob对象它的目标,然后暂停协程,等待bob到达目标时的唤醒呼叫。
在引擎方面,事情可能看起来像这样(伪代码):
class Script:
def __init__(self, filename):
self.coroutine = Coroutine(filename)
self.is_wokenup = True
def wakeup(self):
self.is_wokenup = False;
def update():
if self.is_wokenup:
coroutine.run()
class Character:
def walkto(self, target, script):
self.script = script
self.target = target
def update(self):
if target:
move_one_step_closer_to(self.target)
if close_enough_to(self.target):
self.script.wakeup()
self.target = None
self.script = None
objects = [Character("bob"), Character("jane")]
scripts = [Script("script_file.scr")]
while True:
for obj in objects:
obj.update()
for scr in scripts:
scr.update()
但是,虽然协同程序使编码这些序列变得非常简单,但是并非每个实现都会在编译时考虑到序列化,因此如果你大量使用游戏,游戏节省将成为一个非常麻烦的问题。协程。
这个例子也只是游戏中协程的最基本情况,协程本身也可用于许多其他任务和算法。
答案 2 :(得分:7)
在游戏中可以使用单向协同程序,就像模型中的演员一样轻量级线程,就像在Kamaelia中一样。
游戏中的每个对象都是Kamaelia'组件'。组件是一个对象,可以在允许暂停时通过产生暂停执行。这些组件还具有一个消息传递系统,允许它们以异步方式安全地相互通信。
所有对象都会同时做自己的事情,并在发生交互时向对方发送消息。
所以,它并不是特定于游戏,但是当你有多个通信组件同时执行时,任何事情都可以从协同程序中受益。
答案 3 :(得分:2)
您可能会感兴趣的两个链接:
http://aigamedev.com/open/articles/coroutine-state-machine/
http://www.dabeaz.com/coroutines/(在此页面中搜索“任务”和pdf)
答案 4 :(得分:1)
想要使用协同程序来表示单个actor AI脚本是很常见的。不幸的是,人们往往会忘记协程具有与线程相同的同步和互斥问题,只是在更高的层次上。因此,您通常需要首先尽可能多地消除本地状态,然后编写可靠的方法来处理在您指的内容不再存在时出现的协程中的错误。
所以在实践中他们很难从中受益,这就是为什么像UnrealScript这样的语言使用一些相似的协同程序会将大部分有用的逻辑推向原子事件。有些人从中获得了很好的效用,例如。 EVE在线人员,但他们必须围绕这个概念构建他们的整个系统。 (以及他们如何处理对共享资源的争用没有很好的记录。)