时空幻境|如何实现时光倒流的魔力
如何让游戏中的时间倒退,是一个有趣的问题。我第一次玩这个游戏的时候,还是挺震撼的。也许是第一次遇到这种类型的游戏。时间倒退的机制引人注目。当时也没多想。现在,如何从程序的角度实现这一机制?
用命令方式实现是一种可能的方法。
定义看似晦涩,其实不难理解。玩游戏的时候,我们会把玩家的输入操作转换成游戏中的一个动作。比如按↑跳转什么的。命令模式定义了一个Command基类,其他操作会继承这个基类,实现execute()和undo(),类似这样:
这样我们就把游戏中物体的动作封装到了Command类中,控制一个角色就相当于执行了一系列的Command命令。这样做的好处是,我们可以记录用户的操作,并将命令保存在一个堆栈中。时光倒流的时候,我们只需要拿出一个又一个command命令,然后执行撤销操作。
命令模式的好处是,各种命令实现后,实现时间倒退、前进、加速、减速都非常简单,只要你一直执行execute或者undo就可以了。缺点也很明显,这些命令不容易实现...
在时空幻境中,主角的动作其实是比较少的,只有跑和跳比较容易实现,但是也有很多其他的物体,它们也是在运动的,可能会和主角发生互动,所以如果使用命令模式的话,实现起来是相当复杂的。
还有一种方式比较暴力,就是memento模式,就是保存游戏状态。
这个模式就不用说了,就是每一帧都保存一个世界当前状态的快照,然后在时间倒退的时候直接读取状态。这种方法的优点是:易写,快。当然缺点是占用内存比较多。
消耗了多少内存?其实可以大致算一下。假设一个关卡中有20个游戏对象需要记录状态,每个对象大约需要6~7个属性(位置、移动速度和其他属性等。,这里不太确定,但我觉得应该不需要太多属性)。位置之外,其他属性应该不需要很高的精度,可以优化,但是这里还是先按照8个字节计算。那么游戏运行1小时所需内存为:
一帧所需的内存= 20 68 = 960(字节)**
如果一秒设置为60帧,那么内存消耗= 960 * 60 = 57600(字节)。
* *一小时的内存消耗= 57600 * 3600/1024/1024 = 197(MB)* *
接近200MB的消耗!这确实很多,但也不是不可能。还有很多优化方案,比如减少保存属性的字节。或者用增量保存的方法,不要无帧保存所有的值,保存改变后的值,这样会节省很多无效内存,因为很多时候,玩家可能是站在某个地方傻傻的。
用上面的方法,应该可以留下一半以上的记忆。另外,一章一个小时应该没几个人玩,大概10~20分钟基本可以完成。其实这个数字还是挺理想的。
本来这里快结束了,但是我发现了一个帖子:binator.com/item?. id = 9484197
这大概是作者对游戏机制实现的回答(应该是从语气上)。虽然英语很差,但我大概能听懂。
也就是说,作者大多记录的是世界的状态,而不是事件(第五章除外)。其实上面两种模式作者都用,而且意思是用命令模式很烦,写相反的状态也很复杂。
作者还说CPU消耗是比内存消耗更大的问题,所以选择了保存状态的方法。在Xbox 360上,它实际上可以运行大约30-45分钟,然后内存缓冲才会耗尽。CPU消耗高的应该是命令模式在需要执行大量命令的时候可能会进行大量的计算,如果玩家加速操作可能会更伤。
另外,如果缓冲耗尽,那么就丢弃初始状态,这样虽然不能回到初始状态,但是作者说好像没什么注意到这一点。
不知道有没有更好的实现方式,感觉挺暴力的...