游戏设计中的协程?
5 个回答
最常见的协程应用可能是在老式的图形点选冒险游戏中,它们被用来编写过场动画和其他游戏中的动画序列。一个简单的代码示例看起来是这样的:
# script_file.scr
bob.walkto(jane)
bob.lookat(jane)
bob.say("How are you?")
wait(2)
jane.say("Fine")
...
这个整个动画序列不能像普通代码那样写,因为你希望在执行完 bob.walkto(jane)
之后看到 bob 的走路动画,而不是直接跳到下一行。为了让走路动画播放,你需要把控制权交还给游戏引擎,这就是协程发挥作用的地方。
这个整个序列是作为一个协程来执行的,这意味着你可以随时暂停和恢复它。像 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()
不过要提醒一下,虽然协程让编写这些序列变得非常简单,但并不是所有的实现都考虑到了序列化,所以如果你大量使用协程,游戏存档可能会变得相当麻烦。
这个例子只是游戏中协程的最基本用法,实际上,协程还可以用于很多其他任务和算法。
协程让我们可以创建很多非常轻量级的“微线程”,并且这些微线程可以进行合作式的多任务处理(也就是说,微线程可以主动暂停自己,让其他微线程运行)。如果想了解更多,可以看看Dave Beazley的文章。
这种微线程在游戏编程中显然非常有用。想象一下一个实时战略游戏,里面有很多单位,每个单位都有自己的思考方式。在这种情况下,让每个单位的人工智能作为微线程在你模拟的多任务环境中运行,可能会非常方便。这只是一个例子,肯定还有更多的应用。
在谷歌上搜索“协程游戏编程”似乎会出现一些有趣的结果。
在游戏中,一种使用协程的方法是把它们当作轻量级线程,像在Kamaelia这样的演员模型。
游戏中的每个对象都可以看作是一个Kamaelia的“组件”。这个组件是一个可以在允许暂停的时候暂停执行的对象。组件之间还有一个消息系统,可以让它们安全地异步交流。
所有的对象可以同时各自做自己的事情,当发生互动时,它们会互相发送消息。
所以,这种方法不仅仅适用于游戏,任何有很多组件同时交流的场景都可以从协程中受益。