数据存档和读档三种方式

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using LitJson;
using System.Xml;

public class GameManager : MonoBehaviour
{
    public static GameManager _instance;

//是否是暂停状态
    public bool isPaused = true;
    public GameObject menuGO;

public GameObject[] targetGOs;

private void Awake()
    {
        _instance = this;
        //游戏开始时是暂停的状态
        Pause();
    }

private void Update()
    {
        //判断是否按下ESC键,按下的话,调出Menu菜单,并将游戏状态更改为暂停状态
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            Pause();
        }
    }

//暂停状态
    private void Pause()
    {
        isPaused = true;
        menuGO.SetActive(true);
        Time.timeScale = 0;
        Cursor.visible = true;
    }
    //非暂停状态
    private void UnPause()
    {
        isPaused = false;
        menuGO.SetActive(false);
        Time.timeScale = 1;
        Cursor.visible = false;

}

//创建Save对象并存储当前游戏状态信息
    private Save CreateSaveGO()
    {
        //新建Save对象
        Save save = new Save();
        //遍历所有的target
        //如果其中有处于激活状态的怪物,就把该target的位置信息和激活状态的怪物的类型添加到List中
        foreach (GameObject targetGO in targetGOs)
        {
            TargetManager targetManager = targetGO.GetComponent<TargetManager>();
            if (targetManager.activeMonster != null)
            {
                save.livingTargetPositions.Add(targetManager.targetPosition);
                int type = targetManager.activeMonster.GetComponent<MonsterManager>().monsterType;
                save.livingMonsterTypes.Add(type);
            }
        }
        //把shootNum和score保存在Save对象中
        save.shootNum = UIManager._instance.shootNum;
        save.score = UIManager._instance.score;
        //返回该Save对象
        return save;
    }

//通过读档信息重置我们的游戏状态(分数、激活状态的怪物)
    private void SetGame(Save save)
    {
        //先将所有的targrt里面的怪物清空,并重置所有的计时
        foreach (GameObject targetGO in targetGOs)
        {
            targetGO.GetComponent<TargetManager>().UpdateMonsters();
        }
        //通过反序列化得到的Save对象中存储的信息,激活指定的怪物
        for (int i = 0; i < save.livingTargetPositions.Count; i++)
        {
            int position = save.livingTargetPositions[i];
            int type = save.livingMonsterTypes[i];
            targetGOs[position].GetComponent<TargetManager>().ActivateMonsterByType(type);
        }

//更新UI显示
        UIManager._instance.shootNum = save.shootNum;
        UIManager._instance.score = save.score;
        //调整为未暂停状态
        UnPause();
    }

//二进制方法:存档和读档
    private void SaveByBin()
    {
        //序列化过程(将Save对象转换为字节流)
        //创建Save对象并保存当前游戏状态
        Save save = CreateSaveGO();
        //创建一个二进制格式化程序
        BinaryFormatter bf = new BinaryFormatter();
        //创建一个文件流
        FileStream fileStream = File.Create(Application.dataPath + "/StreamingFile" + "/byBin.txt");
        //用二进制格式化程序的序列化方法来序列化Save对象,参数:创建的文件流和需要序列化的对象
        bf.Serialize(fileStream, save);
        //关闭流
        fileStream.Close();

//如果文件存在,则显示保存成功
        if (File.Exists(Application.dataPath + "/StreamingFile" + "/byBin.txt"))
        {
            UIManager._instance.ShowMessage("保存成功");
        }
    }

private void LoadByBin()
    {
        if (File.Exists(Application.dataPath + "/StreamingFile" + "/byBin.txt"))
        {
            //反序列化过程
            //创建一个二进制格式化程序
            BinaryFormatter bf = new BinaryFormatter();
            //打开一个文件流
            FileStream fileStream = File.Open(Application.dataPath + "/StreamingFile" + "/byBin.txt", FileMode.Open);
            //调用格式化程序的反序列化方法,将文件流转换为一个Save对象
            Save save = (Save)bf.Deserialize(fileStream);
            //关闭文件流
            fileStream.Close();

SetGame(save);
            UIManager._instance.ShowMessage("");

}
        else
        {
            UIManager._instance.ShowMessage("存档文件不存在");
        }

}

//XML:存档和读档
    private void SaveByXml()
    {
        Save save = CreateSaveGO();
        //创建XML文件的存储路径
        string filePath = Application.dataPath + "/StreamingFile" + "/byXML.txt";
        //创建XML文档
        XmlDocument xmlDoc = new XmlDocument();
        //创建根节点,即最上层节点
        XmlElement root = xmlDoc.CreateElement("save");
        //设置根节点中的值
        root.SetAttribute("name", "saveFile1");

//创建XmlElement
        XmlElement target;
        XmlElement targetPosition;
        XmlElement monsterType;

//遍历save中存储的数据,将数据转换成XML格式
        for (int i = 0; i < save.livingTargetPositions.Count; i++)
        {
            target = xmlDoc.CreateElement("target");
            targetPosition = xmlDoc.CreateElement("targetPosition");
            //设置InnerText值
            targetPosition.InnerText = save.livingTargetPositions[i].ToString();
            monsterType = xmlDoc.CreateElement("monsterType");
            monsterType.InnerText = save.livingMonsterTypes[i].ToString();

//设置节点间的层级关系 root -- target -- (targetPosition, monsterType)
            target.AppendChild(targetPosition);
            target.AppendChild(monsterType);
            root.AppendChild(target);
        }

//设置射击数和分数节点并设置层级关系  xmlDoc -- root --(target-- (targetPosition, monsterType), shootNum, score)
        XmlElement shootNum = xmlDoc.CreateElement("shootNum");
        shootNum.InnerText = save.shootNum.ToString();
        root.AppendChild(shootNum);

XmlElement score = xmlDoc.CreateElement("score");
        score.InnerText = save.score.ToString();
        root.AppendChild(score);

xmlDoc.AppendChild(root);
        xmlDoc.Save(filePath);

if (File.Exists(Application.dataPath + "/StreamingFile" + "/byXML.txt"))
        {
            UIManager._instance.ShowMessage("保存成功");
        }
    }

private void LoadByXml()
    {
        string filePath = Application.dataPath + "/StreamingFile" + "/byXML.txt";
        if (File.Exists(filePath))
        {
            Save save = new Save();
            //加载XML文档
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(filePath);

//通过节点名称来获取元素,结果为XmlNodeList类型
            XmlNodeList targets = xmlDoc.GetElementsByTagName("target");
            //遍历所有的target节点,并获得子节点和子节点的InnerText
            if (targets.Count != 0)
            {
                foreach (XmlNode target in targets)
                {
                    XmlNode targetPosition = target.ChildNodes[0];
                    int targetPositionIndex = int.Parse(targetPosition.InnerText);
                    //把得到的值存储到save中
                    save.livingTargetPositions.Add(targetPositionIndex);

XmlNode monsterType = target.ChildNodes[1];
                    int monsterTypeIndex = int.Parse(monsterType.InnerText);
                    save.livingMonsterTypes.Add(monsterTypeIndex);
                }
            }

//得到存储的射击数和分数
            XmlNodeList shootNum = xmlDoc.GetElementsByTagName("shootNum");
            int shootNumCount = int.Parse(shootNum[0].InnerText);
            save.shootNum = shootNumCount;

XmlNodeList score = xmlDoc.GetElementsByTagName("score");
            int scoreCount = int.Parse(score[0].InnerText);
            save.score = scoreCount;

SetGame(save);
            UIManager._instance.ShowMessage("");

}
        else
        {
            UIManager._instance.ShowMessage("存档文件不存在");
        }
    }

//JSON:存档和读档
    private void SaveByJson()
    {
        Save save = CreateSaveGO();
        string filePath = Application.dataPath + "/StreamingFile" + "/byJson.json";
        //利用JsonMapper将save对象转换为Json格式的字符串
        string saveJsonStr = JsonMapper.ToJson(save);
        //将这个字符串写入到文件中
        //创建一个StreamWriter,并将字符串写入文件中
        StreamWriter sw = new StreamWriter(filePath);
        sw.Write(saveJsonStr);
        //关闭StreamWriter
        sw.Close();

UIManager._instance.ShowMessage("保存成功");
    }

private void LoadByJson()
    {
        string filePath = Application.dataPath + "/StreamingFile" + "/byJson.json";
        if (File.Exists(filePath))
        {
            //创建一个StreamReader,用来读取流
            StreamReader sr = new StreamReader(filePath);
            //将读取到的流赋值给jsonStr
            string jsonStr = sr.ReadToEnd();
            //关闭
            sr.Close();

//将字符串jsonStr转换为Save对象
            Save save = JsonMapper.ToObject<Save>(jsonStr);
            SetGame(save);
            UIManager._instance.ShowMessage("");
        }
        else
        {
            UIManager._instance.ShowMessage("存档文件不存在");
        }
    }

//从暂停状态恢复到非暂停状态
    public void ContinueGame()
    {
        UnPause();
        UIManager._instance.ShowMessage("");
    }

//重新开始游戏
    public void NewGame()
    {
        foreach (GameObject targetGO in targetGOs)
        {
            targetGO.GetComponent<TargetManager>().UpdateMonsters();
        }
        UIManager._instance.shootNum = 0;
        UIManager._instance.score = 0;
        UIManager._instance.ShowMessage("");
        UnPause();
    }

//退出游戏
    public void QuitGame()
    {
        Application.Quit();
    }

//保存游戏
    public void SaveGame()
    {
        //SaveByBin();
        //SaveByJson();
        SaveByXml();
    }

//加载游戏
    public void LoadGame()
    {
        //LoadByBin();
        //LoadByJson();  
        LoadByXml();
    }

}

原文地址:https://www.cnblogs.com/xiaomao21/p/9128117.html

时间: 2024-08-04 12:48:31

数据存档和读档三种方式的相关文章

Unity开发之存档和读档的三种实现方式

此文内容源自siki学院视频,仅供学习!视频链接地址:http://www.sikiedu.com/course/129 工程使用Unity 2017.3.0f3 (64-bit) 老司机读博客,了解存档读档主体实现方式即可,仅供借鉴参考,菜鸟可以去文章结尾下载源码,或者去上面的链接直接观看视频..... 首先,创建一个Save类用于保存数据 [System.Serializable]public class Save{ public List<int> livingTargetPositio

(转载)Android数据存储三种方式总结

本文转载自:http://www.cnblogs.com/ITtangtang/p/3920916.html 本文介绍Android平台进行数据存储的三大方式,分别如下: 1 使用SharedPreferences存储数据 2 文件存储数据 3 SQLite数据库存储数据 其他: 4 使用ContentProvider存储数据 5 网络存储数据 下面详细讲解这五种方式的特点 第一种: 使用SharedPreferences存储数据     适用范围:保存少量的数据,且这些数据的格式非常简单:字符

ios网络学习------4 UIWebView的加载本地数据的三种方式

UIWebView是IOS内置的浏览器,可以浏览网页,打开文档  html/htm  pdf   docx  txt等格式的文件.  safari浏览器就是通过UIWebView做的. 服务器将MIME的标识符等放入传送的数据中告诉浏览器使用那种插件读取相关文件. uiwebview加载各种本地文件(通过loadData方法): - (void)viewDidLoad { [super viewDidLoad]; [self setupUI]; NSString *path = [[NSBund

数据导入HBase最常用的三种方式及实践分析

数据导入HBase最常用的三种方式及实践分析         摘要:要使用Hadoop,需要将现有的各种类型的数据库或数据文件中的数据导入HBase.一般而言,有三种常见方式:使用HBase的API中的Put方法,使用HBase 的bulk load工具和使用定制的MapReduce Job方式.本文均有详细描述. [编者按]要使用Hadoop,数据合并至关重要,HBase应用甚广.一般而言,需要 针对不同情景模式将现有的各种类型的数据库或数据文件中的数据转入至HBase 中.常见方式为:使用H

SpringMVC返回json数据的三种方式

SpringMVC返回json数据的三种方式:http://blog.csdn.net/shan9liang/article/details/42181345 上述第三种方法:可能会出现这个jar包没有的情况,引入即可,下面pom引入即可 java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/JsonProcessingException

java中内部类的创建四种情况,三种方式,及内部数据访问权限

内部类和外部类的关系,及内部静态类的数据访问权限,声明方式. 第一种,在外部类内部声明使用内部类,内部类的类型为static和非 static类型,内部类数据类型为private,protected,public 类型的访问权限.外部类为非静态声明和权限如下: package com; public class Test1 { //@author 张春蕾 private class Name{ private int i =1; public int s = 2; protected int m

django获取单表数据的三种方式

django获取单表数据的三种方式 v1 = models.Business.objects.all() # QuerySet ,内部元素都是对象 v2 = models.Business.objects.all().values('id','caption') # QuerySet ,内部元素都是字典 v3 = models.Business.objects.all().values_list('id','caption') # QuerySet ,内部元素都是元组 def business(

oracle数据的导入导出(两种方法三种方式)

大概了解数据库中数据的导入导出.在oracle中,导入导出数据的方法有两种,一种是使用cmd命令行的形式导入导出数据,另一种是使用PL/SQL工具导入导出数据. 1,使用cmd命令行导入导出数据 1.1整库导出 整库导出:exp 管理员账号/密码 full=y;//参数full表示整库导出.导出后会在当前目录下生成一个EXPDAT.DMP的文件,此文件为备份文件.如果想导出数据到指定位置,并且取个名字,需要添加file参数.例如:exp system/123456 file= C:\person

Entity Framework加载数据的三种方式。

MSDN文章Loading Related Entities 有 Eagerly Loading Lazy Loading Explicitly Loading 三种方式. 而看到查询中包含Include方法就知道是Eagerly Loading.