• 使用Xamarin开发移动应用示例——数独游戏(五)保存游戏进度


    项目代码可以从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);
                }
    

    状态保存完成了。下一步,我们引入数据库,保存游戏结果,并增加新游戏的录入功能。

  • 相关阅读:
    JS中利用正则表达式提取一个字符串中的子字符串的方法
    Xcode的环境变量列表
    在未安装Visual Studio 2012的服务器上使用MSBuild以文件系统方式发布ASP.NET MVC系统
    使Web API支持二级实体操作,兼对RESTFul风格API设计的疑惑。
    忽略大小写的字符串包含测试
    Entity Framework里不用查询直接更新的办法
    iOS里生成灰化(黑白)图像
    微信小程序开发调试工具
    微信小程序产品定位及功能介绍
    微信小程序DEMO初体验
  • 原文地址:https://www.cnblogs.com/zhenl/p/15834748.html
Copyright © 2020-2023  润新知