作者ddavid (谎言接线生)
看板GameDesign
标题Re: [问题] 游戏存档、纪录档问题
时间Sun Aug 1 19:39:52 2010
※ 引述《F23ko (纯洁)》之铭言:
: 但是有一些比较复杂的东西
: 例如:
: 匿名函式
: (塞到委派中的匿名函式,读取起来有困难,我要怎麽知道委派中的匿名函式是哪一个?)
请帮你的class多一个属性,上面记载现在是哪一个。
: 二元树的节点
: (我怎麽知道哪个节点连接哪个节点?只能全部读取出来,写入档案吗?
: 这样到读档的时候又要再重新插入一次)
有两种比较直接的方法存二元树:
1. 假如是Complete binary tree,那可以让Node的编号从Node[1]开始,Node[n]的
Children一定是Node[2*n]跟Node[2*n+1],这样你只要照层数BFS下来存就好。
2. 如果是任意的binary tree,那除了硬填成Complete来处理以外,你也可以用DFS
递回下去,除了照DFS顺序存资料以外再加存「过程」,比如回到上一层的这个动作
,然後读出来就可以完全照这个顺序重现。
但事实上,假设你的二元树有确保某些性质,让它不会因为资料进来的顺序而造
成(有影响的)改变,或是你根本没有用到那麽详细的二元树性质,那其实你就DFS
或BFS跑一次资料一一存下来就好了,下次读档再重建。重建的树可能跟原本长得不
一样,但是如果用不上那些性质那就不需要困扰自己,比如说你建个Binary search
tree只是为了加速查找的速度,顺序对你来说是不重要的。至於你说「到读档的时候
又要再重新插入一次」,那存得再烂大不了也就是O(nlogn) vs O(n)而已,但却可以
让你不用多存资料以外的其它资讯,也不用为读档写出一个新的Function,而只要使
用原本的Insert就好了。
: =======================================================================
: 还有所谓的「游戏记录档」之类的东西
: 就是能将游戏给「录」下来
: 我觉得是,将玩家以及AI的指令、乱数记录下来後,再用游戏的引擎去播放
: 很好,我觉得这会造成程式中「散布」一堆纪录、播放用的程式码
: 撰写、除错起来可能会有困难......
你没有想到一点,那就是这堆纪录、播放用的程式码本身就可以拿来当作Debug
Code,所以你应该让它能够被拿掉而完全不影响原本的程式。所以第一种方法是你可
以这样做:
#define REPLAY
.
.
.
// 一般执行用的Code
#if REPLAY
// Replay用的Code
#endif
// 一般执行用的Code
这样你要对原本的Code做Debug,就把#define那行注解掉就好。
第二种方法是写一个独立的class,并提供Method来做动作记录:
class Replay
{
// 要定义的属性包括所有要记录的资讯
public void SaveAction(Action Act);
public Action GetNextAction();
public bool Save(string Filename);
}
然後你要记录某个动作就在该处call SaveAction()这样,要播放就是一个回圈
跑GetNextAction()然後照着拿出来的Action做动作,最後用Save()直接写成档这样
。
而Action也是个class,唯一的重点是它要实做出一些Method,其中一个Method
代表在游戏中实际去做这个动作。另外还要有存取档案的功能,这样Replay就只要依
序Call每个存下来Action的存入功能就能存档,同样的反覆Create新的空Action做读
取直到不能读也就是读档完成了。但依情况而定,存取档案也可以做在Replay那一层
里面,但还是要有提供出Method把资料交给Replay就是。
以上不是唯二的方法,我也只是线上随想随写,但这应该是很直觉且也不算太差
的做法。其中可能有些小错或没想详细,不过方向应该大致没问题。
: 所以我觉得我想的方法不好
: 请问这种功能一般是如何实现?
--
「如果你没法给我个解释的话,死一万次也不能弥补你的过错!」
「我没办法死一万次赔你啊。」
「可是你有办法半死两万次,知道吗,嗯?」
--莲.席斯塔
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 111.250.175.242
1F:推 F23ko:谢谢回答,但我需要花些时间去思考..... 08/01 19:47