看板 GameDesign 關於我們 聯絡資訊
※ 引述《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
F23ko:謝謝回答,但我需要花些時間去思考..... 08/01 19:47