上篇写了一个备忘录模式的简单例子模板,这次来看看具体的实现应用。
这里列出上篇的地址: https://blog.csdn.net/liaoshengg/article/details/82530426
现在首先来看需求:
在《P级阵地》的成就系统,只需保存每一项成就系统的最佳记录,并不需要保留多个版本,因此,在运用备忘录模式时,省去了Caretaker记录保存者的实现
public class AchievementSaveData{
//要存盘的成就记录
public int EnemyKilledCount{get;set;}
public int SolderKilledCount{get;set;}
public int StageLc{get;set;}
public void SaveData(){
PlayerPrefs.SetInt("EnemyKilledCount",EnemyKilledCount);
PlayerPrefs.SetInt("SoldierKilledCount",SoldierKilledCount);
PlayerPrefs.SetInt("StageLv,StageLv");
public void LoadData(){
EnemyKilledCount = PlayerPrefs.GetInt("EnemykilledCount",0);
SoldierKilledCount = PlayerPrefs.GetInt("SoldierkilledCount",0);
StageLv = PlayerPrefs.GetInt("StageLv",0);
}
}
该类用来存储记录的信息,并提供Set Get 方法来存储和加载这些记录。
public class AchievemenSystem : IGameSystem{
//最后一次的存盘记录
priavte AchievementSaveData m_LastSaveData = null;
//记录的成就项目
private int m_EnemyKilledCount = 0;
private int m_SoldierKilledCount = 0;
private int m_StageLv = 0;
//产生存盘的数据
public AchievementSaveData CreateSaveData(){
AchievementSaveData SaveData = new AchievementSavaData();
//设置新的高分者
SavaData.EnemyKilledCount = Mathf.Max(m_EnemyKilledCount,m_LastSaveData.EnemyKilledCoun);
SaveData.SoldierKilledCount = Mathf.Max(m_SoldierKilledCount,m_LastSaveData.SoldierKilledCount);
SaveData.StageLv = Mathf.Max(m_StageLv,m_LastSaveData.StageLv);
return SaveData;
}
public void SetSaveData(AchievementSaveData SaveData){
m_LastSaveData = SaveData;
}
}
成就系统访问数据的方法被删除了,而是产生一个成就记录存盘类,并间接通过记录存盘类来存储成就信息,这就是记录存盘方法。
并且新增了一个Set方法来恢复记录存盘
接下来就是调用存盘方法了,根据需求来看即可。
书中介绍,因为不必实现保存多个记录存盘版本,并为了配合游戏系统的运行,所以将成就系统与成就记录存盘的一并实现放在PBaseDefneseGame类
public class PBaseDefenseGame{
//存盘
private void SavaData(){
AchievementSaveData SavaData = m_AchievementSystem.CreateSaveData();
SavaData.SavaData();
}
//读取存盘记录
private AchievementSaveData LoadData(){
AchievementSaveData oldData = new AchievementSaveData();
OldData.LoadData();
m_AcievementSystem.SetSaveData(OldData);
return OldData;
}
}
PBaseDefenseGame是一个用了外观模式,中介者模式的类,当外界或其他游戏系统需要存盘,读盘功能时,调用直接通过类对象方法即可。
public class GamePauseUI : IUserInterface{
private Text m_EnemyKilledCountText = null;
private Text m_SoldierKilledCountText = null;
private Text m_StageLvCountText = null;
//...
//显示暂停
public void showGamePause(AchievementSaveData SaveData){
m_EnemyKilledCountText.text = string.Format("当前杀敌数总和:{0}",SaveData.EnemyKilledCount);
m_SoldierKilledCountText .text = string.Format("当前我方单位阵亡总和:{0}",SaveData.SoldierKilledCount);
m_StageLvCountText.text = string.Format("最高关卡数:{0}",SaveData.StageLv);
Show();
}
}
除了保存记录,还需要把信息显示在UI上,可以直接使用这个成就记录存盘的信息。
使用备忘录模式的优点:
在运用备忘录模式之后,记录成就的功能就从成就系统中独立出来,让专职的AchievementSaveData类负责存盘的公众,至于AchievementSaveData类该怎么实现存盘功能,成就系统也不必知道。并且成就系统本身也保留封装性,不必对外开放过多的存取函数来获取类的内部的状态,信息的设置和恢复都在成就系统内部完成。
实现备忘录模式的注意事项
当每个游戏系统都有存盘的需求时,负责保存记录类会过于庞大,此时可以让各个系统的存盘以结构化方式编排,或是内部再以子类的方式加以规划。
可以配合串行化工具,先将存盘信息转换成XML或Json格式,然后使用存盘工具来保存那些已转换好的格式数据,这样能减少针对每一项存盘信息读写的实现。
备忘录模式面对变化时
一般单机游戏都可以提供存盘功能,而且存盘的数量不止一份。
或是多人共同游玩时,就需要加入多份存盘的功能,此时系统就可以增加Caretaker类来维护。
如果不止一个系统需要存盘功能,那么可以增加一个游戏存盘系统,将原有的数据类声明为该类的成员,再加入其它系统的存盘类,统一由存盘系统(GameDataSaver)负责实现,而且还可以同时扮演Caretaker的角色来维护多个版本的存盘功能。