项目代码可以从Github下载:https://github.com/zhenl/ZL.Shudu 。代码随项目进度更新。
保存进度是移动应用的基本功能,在应用的使用过程中会有各种各样的可能导致使用中断,再次回到应用时,应该恢复到中断前的状态。前面我们已经初步完成了数独游戏,但还不具备状态保存的功能,现在我们增加这个功能,将游戏进度保存到本地文件中。
首先确定在什么地方保存和恢复状态。在Xamarin的View退出时会触发OnDisappearing事件,在这个事件中可以保存游戏的进度。在View再次显示时,首先判断是否存在以保存的进度,如果存在,就恢复状态,否则创建新的游戏。
然后确定需要保存的内容,需要保存当前已经输入的数字和位置,还需要保存输入的过程以及花费的时间。
还有就是保存的位置,Xamarin提供了每个应用保存数据的抽象位置,我们可以使用Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)来获取路径而不需要考虑设备类型。
所有这些确定好之后,就可以编写相应的逻辑了。
首先是保存状态的方法:
private void Save(string filename) { try { var strchess = ""; for (var i = 0; i < 9; i++) { for (var j = 0; j < 9; j++) { strchess += chess[i, j].ToString(); } } strchess += " "; for (var i = 0; i < 9; i++) { for (var j = 0; j < 9; j++) { strchess += string.IsNullOrEmpty(buttons[i, j].Text) ? "0" : buttons[i, j].Text; } } strchess += " "; foreach (var str in steps) { strchess += str + ";"; } strchess += " "; strchess += (DateTime.Now - dtBegin).Ticks.ToString(); string _fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), filename); File.WriteAllText(_fileName, strchess); } catch (Exception ex) { lbMessage.Text = ex.Message; } }在OnDisappearing事件响应中调用这个方法:
protected override void OnDisappearing() { Save("shudu_current.txt"); }恢复状态的函数如下:
private bool OpenCurrent() { try { string _fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "shudu_current.txt"); if (File.Exists(_fileName)) { var strchess = File.ReadAllText(_fileName); int[,] fchess = new int[9, 9]; var arr = strchess.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); for (var i = 0; i < 9; i++) { for (var j = 0; j < 9; j++) { chess[i, j] = int.Parse(arr[0].Substring(i * 9 + j, 1)); fchess[i, j] = int.Parse(arr[1].Substring(i * 9 + j, 1)); } } for (var i = 0; i < 9; i++) { for (var j = 0; j < 9; j++) { var btn = buttons[i, j]; if (chess[i, j] > 0) { btn.Text = chess[i, j].ToString(); } else { btn.Text = fchess[i, j] > 0 ? fchess[i, j].ToString() : ""; } btn.IsEnabled = chess[i, j] == 0; int m = i / 3; int n = j / 3; var c = new Color(0.9, 0.9, 0.9); if ((m + n) % 2 == 0) { c = new Color(0.7, 0.7, 0.7); } btn.BackgroundColor = c; } } if (arr.Length > 2) { var steparr = arr[2].Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); steps.Clear(); foreach(var step in steparr) steps.Push(step); } if (arr.Length > 3) { currentDiffer = long.Parse(arr[3]); } dtBegin = DateTime.Now; return true; } } catch (Exception ex) { lbMessage.Text = ex.Message; } return false; }在初始化时调用这个函数:
public Game() { try { InitializeComponent(); SetNumButtons(); SetLayout(); if (!OpenCurrent()) SetNewGame(); } catch (Exception ex) { lbMessage.IsVisible = true; rowResult.Height = 40; lbMessage.Text = ex.Message; //throw; } }最后,在游戏完成时删除状态文件:
if (IsFinish()) { lbFinish.IsVisible = true; lbTime.IsVisible = true; rowResult.Height = 40; var diff = (DateTime.Now.Ticks - dtBegin.Ticks + currentDiffer) / 10000 / 1000 / 60; lbTime.Text = diff + "分钟"; string _fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "shudu_current.txt"); File.Delete(_fileName); }状态保存完成了。下一步,我们引入数据库,保存游戏结果,并增加新游戏的录入功能。
本文来自博客园,作者:寻找无名的特质,转载请注明原文链接:https://www.cnblogs.com/zhenl/p/15834748.html