日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

打游戏要存进度-备忘录模式

發布時間:2023/12/6 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 打游戏要存进度-备忘录模式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

打游戲要存進度-備忘錄模式

學習自

《大話設計模式》

備忘錄模式漫談

備忘錄的這種設計思想是非常常見的,比如說圍棋游戲的悔棋,繪圖軟件的撤銷功能等等,都或多或少的使用了備忘錄模式來處理對象的狀態。

備忘錄(Memento): 在不破壞封裝性的前提下,捕獲一個對象的內部狀態,并在該對象之外保存這種狀態。這樣以后就可以將該對象恢復到原來保存的狀態。

我的理解
保存好重要數據以備反悔之時使用。

備忘錄模式類圖

  • Originator:是備忘錄的創建者
  • Memento: 是備忘錄對象
  • Caretaker: 持有備忘錄對象

沒有使用備忘錄模式的代碼

下面這一段代碼是模擬了一下,在玩游戲的時候對角色狀態的存檔與恢復。

public class GameRole {public int Vitality { get; set; }public int Attack { get; set; }public int Defense { get; set; }public void StateDisplay(){Console.WriteLine("角色當前狀態");Console.WriteLine("體力:{0}", this.Vitality);Console.WriteLine("攻擊力:{0}", this.Attack);Console.WriteLine("防御力:{0}", this.Defense);Console.WriteLine();}public void GetInitState(){this.Vitality = 100;this.Attack = 100;this.Defense = 100;}public void Fight(){this.Vitality = 0;this.Attack = 0;this.Defense = 0;} }static void Main(string[] args) {GameRole gr = new GameRole();gr.GetInitState();gr.StateDisplay();//保存進度//!! 這里暴露了細節GameRole grBackup = new GameRole();grBackup.Vitality = gr.Vitality;grBackup.Attack = gr.Attack;grBackup.Defense = gr.Defense;gr.Fight();gr.StateDisplay();//回復之前的狀態//!!這里暴露的細節gr.Vitality = grBackup.Vitality;gr.Attack = grBackup.Attack;gr.Defense = grBackup.Defense;gr.StateDisplay();Console.ReadKey(); }//輸出結果 角色當前狀態 體力:100 攻擊力:100 防御力:100角色當前狀態 體力:0 攻擊力:0 防御力:0角色當前狀態 體力:100 攻擊力:100 防御力:100

上面的代碼將所有的細節暴露給了客戶端,導致客戶端承擔了太多的職責(保存狀態,恢復狀態,進行游戲),而且如果一旦游戲人物的屬性修改或者添加了,那么客戶端相關的代碼也必須修改,這些代碼緊緊地耦合在了一起。

使用了備忘錄模式的代碼

首先游戲角色這個類并不一定所有的屬性都需要備份/存檔,我們只需要把我們關系的數據進行存檔即可,為了存檔這些數據我們需要封裝起來,實現職責的分離。

public class RoleStateMemento {public int Vitality { get; set; }public int Attack { get; set; }public int Defense { get; set; }public RoleStateMemento(int vitality, int attack, int defense){this.Vitality = vitality;this.Attack = attack;this.Defense = defense;} }

有了存儲狀態的 Memento 對象后,我們再來修改一下 GameRole 這個類

public class GameRole {public int Vitality { get; set; }public int Attack { get; set; }public int Defense { get; set; }public void StateDisplay(){Console.WriteLine("角色當前狀態");Console.WriteLine("體力:{0}", this.Vitality);Console.WriteLine("攻擊力:{0}", this.Attack);Console.WriteLine("防御力:{0}", this.Defense);Console.WriteLine();}public void GetInitState(){this.Vitality = 100;this.Attack = 100;this.Defense = 100;}public void Fight(){this.Vitality = 0;this.Attack = 0;this.Defense = 0;}/// <summary>/// 存檔狀態/// </summary>/// <returns></returns>public RoleStateMemento SaveRoleState(){return new RoleStateMemento(this.Vitality, this.Attack, this.Defense);}/// <summary>/// 恢復狀態/// </summary>/// <param name="memento"></param>public void RecoveryState(RoleStateMemento memento){this.Vitality = memento.Vitality;this.Attack = memento.Attack;this.Defense = memento.Defense;} }

上面的代碼向較于最初的版本多出了兩個方法 SaveRoleState 和 RecoveryState 用來保存當前的角色狀態和恢復角色的狀態。

現在我們還差一個Memento的持有者

public class RoleStateCaretaker {public RoleStateMemento RoleStateMemento { get; set; } }

接下來我們看看客戶端的調用

static void Main(string[] args) {GameRole gr = new GameRole();gr.GetInitState();gr.StateDisplay();//存檔RoleStateCaretaker caretaker = new RoleStateCaretaker();caretaker.RoleStateMemento = gr.SaveRoleState();//進行游戲gr.Fight();gr.StateDisplay();//恢復狀態 gr.RecoveryState(caretaker.RoleStateMemento);gr.StateDisplay();Console.ReadKey(); } //輸出結果 角色當前狀態 體力:100 攻擊力:100 防御力:100角色當前狀態 體力:0 攻擊力:0 防御力:0角色當前狀態 體力:100 攻擊力:100 防御力:100

現在客戶端已經無法觀察到保存狀態和恢復狀態的細節了,所有的細節都被封裝到了類中,現在如果對保存/恢復狀態的業務進行修改,也不會影響到客戶端的代碼。

備忘錄模式的弊端

如果備忘錄模式需要存儲的狀態數據非常多的話,那么就會非常消耗內存。

轉載于:https://www.cnblogs.com/slyfox/p/9296938.html

總結

以上是生活随笔為你收集整理的打游戏要存进度-备忘录模式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。