代码之家  ›  专栏  ›  技术社区  ›  Kiv

游戏设计的协同程序?

  •  16
  • Kiv  · 技术社区  · 17 年前

    我听说协同程序是构建游戏的好方法(例如。, PEP 342 :“协同程序是表达许多算法的一种自然方式,例如模拟、游戏……)但我很难理解这到底是如何实现的。

    我从这里看到 article 协同程序可以表示状态机中的状态,这些状态机使用调度程序相互转换,但我不清楚这如何应用于一个游戏,其中游戏状态根据多个玩家的移动而变化。

    有没有使用协同程序编写的简单游戏示例?或者有人可以提供一个如何做的草图?

    5 回复  |  直到 17 年前
        1
  •  10
  •   Eli Bendersky    17 年前

    协同程序允许通过协作多任务创建大量非常轻量级的“微线程”(即,微线程随意挂起自己以允许其他微线程运行)。读戴夫·比兹利的书 article 关于这个问题。

    谷歌上的“协同游戏编程”搜索似乎带来了有趣的结果。

        2
  •  10
  •   Grumbel    17 年前

    最突出的协程案例可能是古老的图形点&单击“冒险游戏”,它们用于在游戏中编写剪接场景和其他动画序列的脚本。一个简单的代码示例如下所示:

    # script_file.scr
    bob.walkto(jane)
    bob.lookat(jane)
    bob.say("How are you?")
    wait(2)
    jane.say("Fine")
    ...
    

    这整个序列不能像普通代码那样编写,因为您希望看到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()
    

    这个例子也是游戏中协同程序的最基本情况,协同程序本身也可以用于很多其他任务和算法。

        3
  •  7
  •   Ryan    17 年前

    在游戏中使用协同程序的一种方法是在类似演员的模型中作为轻量级线程,如 Kamaelia .

    游戏中的每个对象都是Kamaelia的“组件”。组件是一个对象,它可以在允许暂停时通过让步来暂停执行。这些组件还有一个消息传递系统,允许它们安全地异步通信。

    所有对象都将同时做自己的事情,当交互发生时,消息会互相发送。

    所以,这并不是真正针对游戏的,但是当您有大量通信组件同时运行时,任何东西都可以从协同路由中受益。

        5
  •  1
  •   Kylotan    17 年前

    想要使用协同程序来表示单个参与者AI脚本是很常见的。不幸的是,人们往往忘记了协同程序与线程在更高层次上有着相同的同步和互斥问题。因此,您通常需要首先尽可能多地消除局部状态,然后编写健壮的方法来处理协同程序中的错误,这些错误是在您所引用的内容不再存在时出现的。

    因此,在实践中,它们很难从中获益,这就是为什么像UnrealScript这样的语言使用了一些相似的协同程序,将许多有用的逻辑推到了原子事件上。有些人从他们身上获得了很好的效用,例如EVE在线人,但他们必须围绕这个概念构建整个系统。(它们如何处理共享资源的争用还没有很好的文档记录。)