使用协程实现游戏状态机

http://www.mohiji.org/2012/12/14/lua-coroutines/

http://www.slideshare.net/naughty_dog/statebased-scripting-in-uncharted-2-among-thieves

lua 中的协程是一个古老的概念,在早期没有多线程的计算机上,使用协程来模拟多线程。在python, erlang, 以及golang中都可以看到类似的概念的影子。

协程特点就是保存了运行时的上下文,方便后续的重入。协程编程模型和传统的基于堆栈的调用和被调用编程模型不同之处在于,协程之间是平等的,而调用和被调用关系是不平等关系。有些问题采用平等编程模型,可以比较简单的解决。最著名的问题就是词法分析问题。

在词法分析程序中,需要对输入流进行处理,从中获取一个一个的token,接着讲token 传入给parser 使用。一种实现方案是先对所有的token 进行分析,最后将所以结果传给parser, 另外一种方案就是使用协程。每分析出一个token之后,就挂起 词法分析程序, 调用parser, 在 parser 需要新的token的时候, 挂起语法分析协程,从上次挂起的词法分析位置,重新执行词法分析程序。


在游戏设计中存在一些的问题适合用协程来解决。例如要做一个cutscene,一系列时间轴动作。这是可以使用coroutine来执行这些动作, 下个动作等待上个动作结束。

代码类似于:  

xxxx(); 

waitForTime(1);

bbbb();

waitForTime(2);


Cocos2dx 支持 lua 脚本,通过cocos2dx 本身的scheduler 来调度一个 update 函数。 在这个函数里面接着 coroutine.resume() 我们的协程。  而这个协程里面就去执行这些序列化的时间轴操作。


那么要实现一个 waitForTime(xxx) 的函数如何实现呢?

function waitForTime(t)

    local passTime = 0

    while passTime < t do

          passTime = passTime+diff

          coroutine.yield() 

   end

end 

这里的diff 是一个全局变量用于记录两次刷新帧之间的时间差的。









原文地址:https://www.cnblogs.com/liyonghelpme/p/4273734.html