惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

宝玉的分享
宝玉的分享
Recent Commits to openclaw:main
Recent Commits to openclaw:main
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
罗磊的独立博客
V
Visual Studio Blog
爱范儿
爱范儿
H
Help Net Security
J
Java Code Geeks
I
InfoQ
Recent Announcements
Recent Announcements
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Recorded Future
Recorded Future
Jina AI
Jina AI
Microsoft Security Blog
Microsoft Security Blog
WordPress大学
WordPress大学
GbyAI
GbyAI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Y
Y Combinator Blog
Google DeepMind News
Google DeepMind News
Scott Helme
Scott Helme
S
SegmentFault 最新的问题
S
Securelist
L
LINUX DO - 热门话题
Cyberwarzone
Cyberwarzone
C
Cisco Blogs
Simon Willison's Weblog
Simon Willison's Weblog
G
Google Developers Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 叶小钗
T
The Blog of Author Tim Ferriss
博客园_首页
B
Blog
F
Fortinet All Blogs
AWS News Blog
AWS News Blog
V
Vulnerabilities – Threatpost
S
Secure Thoughts
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Forbes - Security
Forbes - Security
S
Security @ Cisco Blogs
T
Threat Research - Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
S
Schneier on Security
Project Zero
Project Zero
Martin Fowler
Martin Fowler
C
Cybersecurity and Infrastructure Security Agency CISA
N
Netflix TechBlog - Medium
N
News and Events Feed by Topic

博客园 - 寻找无名的特质

开源轻量级工作流WorkflowCore介绍 C# 使用SpecFlow创建BDD测试用例 开源的.Net 工作流引擎Elsa初试——创建工作流服务器和图形化工作流配置管理应用 Asp.Net Core Identity 多数据库支持 创建NuGet本地包源 使用Visual Studio 2022开发前端 c# 一些警告的处理方法 Kendo UI Grid 批量编辑使用总结 Kendo UI Grid 使用总结 使用PostMan Canary测试受Identity Server 4保护的Web Api GoJS 使用笔记 Asp.Net Core: Swagger 与 Identity Server 4 VS Code开发TypeScript 使用Xamarin开发移动应用示例——数独游戏(八)使用MVVM实现完成游戏列表页面 使用Xamarin开发移动应用示例——数独游戏(七)添加新游戏 使用Xamarin开发移动应用示例——数独游戏(六)使用数据库 使用Xamarin开发移动应用示例——数独游戏(四)产生新游戏算法改进 使用Xamarin开发移动应用示例——数独游戏(三)添加回退和计时功能 使用Xamarin开发移动应用示例——数独游戏(二)创建游戏界面
使用Xamarin开发移动应用示例——数独游戏(五)保存游戏进度
寻找无名的特质 · 2022-01-30 · via 博客园 - 寻找无名的特质

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

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