数据存储与读取——03实例——创建游戏角色

学习笔记适合新手,如有错误请指正。?号处也请各位指点下,谢谢。

定义数据结构

创建CharData类,里边包含了角色名字等信息

public class CharData
{
    public bool created = false;//false:未创建角色 true:已创建角色
    public string name;//名字
    public int occupation;//职业: 0=战士 1=法师
}

数据管理类

加密的过程是通过JsonFx将CharData对象转化成JSON文本数据,经过加密后,写入文件,解密的过程则是加密过程的逆向过程,即从文件里读取加密后的数据并解密,然后用JsonFx将数据转化成CharData对象,如下:

using UnityEngine;
using System.Collections;
using System;
using JsonFx.Json;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;

/// <summary>
/// 数据管理器
/// </summary>
public class DataManager
{
    #region Config
    //文档相对路径
    static string fileName = "Chapter8/8.3/data.dat";
    //Rijndael加密算法的256位秘钥
    static string key = "12348578902223367877723456789012";
    #endregion

    private static CharData CharData_instance;
    public static CharData CharData_Instance {
        get {
            if (CharData_instance == null) {
                if (ExistFile () == false)
                    CharData_instance = new CharData ();
                else
                    Load ();
            }
            return CharData_instance;
        }
        set {
            CharData_instance = value;
            Save ();
        }
    }

    /// <summary>
    /// 是否存在该文件
    /// </summary>
    public static bool ExistFile ()
    {
        return File.Exists (GetDataPath () + "/" + fileName);
    }
    /// <summary>
    /// 删除该文件
    /// </summary>
    public static void DeleteDataFile ()
    {
        if (ExistFile ())
            File.Delete (GetDataPath () + "/" + fileName);
    }
    /// <summary>
    /// 保存该文件
    /// </summary>
    public static void Save ()
    {
        string text = JsonFx.Json.JsonWriter.Serialize (CharData_Instance);
    //    text = Encrypt(text);
        File.WriteAllText (GetDataPath () + "/" + fileName, text);
    }
    /// <summary>
    /// 读取该文件
    /// </summary>
    public static void Load ()
    {
        if (File.Exists (GetDataPath () + "/" + fileName) == false)
            return;

        string orginText = File.ReadAllText (GetDataPath () + "/" + fileName);
    //    orginText = Decrypt(orginText);

        CharData_Instance = JsonFx.Json.JsonReader.Deserialize<CharData> (orginText);
    }
    /// <summary>
    /// 得到设备路径
    /// </summary>
    private static string GetDataPath ()
    {
        if (Application.platform == RuntimePlatform.IPhonePlayer) {
            //iphone路径
            string path = Application.dataPath.Substring (0, Application.dataPath.Length - 5);
            path = path.Substring (0, path.LastIndexOf (‘/‘));
            return path + "/Documents";
        } else if (Application.platform == RuntimePlatform.Android) {
            //安卓路径
            return Application.persistentDataPath + "/";
        } else
        {
            //其他路径
            return Application.dataPath;
        }
    }
    /// <summary>
    /// 字符串加密
    /// </summary>
    private static string Encrypt (string toE)
    {
        byte[] keyArray = UTF8Encoding.UTF8.GetBytes (key);

        RijndaelManaged rDel = new RijndaelManaged ();
        rDel.Key = keyArray;
        rDel.Mode = CipherMode.ECB;
        rDel.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = rDel.CreateEncryptor ();

        byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes (toE);
        byte[] resultArray = cTransform.TransformFinalBlock (toEncryptArray, 0, toEncryptArray.Length);

        return Convert.ToBase64String (resultArray, 0, resultArray.Length);
    }
    /// <summary>
    /// 字符串解密
    /// </summary>
    private static string Decrypt (string toD)
    {
        byte[] keyArray = UTF8Encoding.UTF8.GetBytes (key);

        RijndaelManaged rDel = new RijndaelManaged ();
        rDel.Key = keyArray;
        rDel.Mode = CipherMode.ECB;
        rDel.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = rDel.CreateDecryptor ();

        byte[] toEncryptArray = Convert.FromBase64String (toD);
        byte[] resultArray = cTransform.TransformFinalBlock (toEncryptArray, 0, toEncryptArray.Length);

        return UTF8Encoding.UTF8.GetString (resultArray);
    }
}

创建界面

创建角色页面page_create和剧情页面page_srart

脚本里首先获取了名字输入框等UI组件,然后通过CharData对象里的created参数判断是否创建了角色,如果没有显示创建角色页面,反之则显示剧情页面

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class C_10_3 : MonoBehaviour {
    public GameObject page_create;//创建角色页面
    public InputField inputField_name;//名字输入
    public Toggle toggle_warrior;//选择按钮:战士

    public GameObject page_start;//剧情页面
    public Text start_text;//剧情文字

    string[] OccupationCn = {"战士","魔法师"};//职业中文名
    void Start()
    {
        if(!DataManager.CharData_Instance.created)
        {
            //如果尚未创建角色,则显示创建角色页面
            page_create.SetActive(true);
            page_start.SetActive(false);
        }
        else
        {
            //已经创建角色,则显示剧情页面
            StartGame();
        }
    }

    /// <summary>
    /// 点击创建按钮
    /// </summary>
    public void On_Create()
    {
        //如果玩家没有填写名字,可以提醒玩家
        if(string.IsNullOrEmpty(inputField_name.text))
        {
            Debug.Log("尚未填写名字");
            return;
        }

        //创建角色
        DataManager.CharData_Instance.created = true;//设置已创建标记
        DataManager.CharData_Instance.name = inputField_name.text;//保存名字

        //保存职业
        if(toggle_warrior.isOn)
            DataManager.CharData_Instance.occupation = 0;
        else
            DataManager.CharData_Instance.occupation = 1;
        //保存数据
        DataManager.Save();
        //显示剧情页面
        StartGame();
    }

    /// <summary>
    /// 显示剧情页面
    /// </summary>
    void StartGame()
    {
        page_create.SetActive(false);//隐藏创建角色页面
        page_start.SetActive(true);//显示剧情页面

        //获取职业中文名
        string occCn = OccupationCn[DataManager.CharData_Instance.occupation];
        //剧情文字
        start_text.text = string.Format(
            "\t在这片美丽富饶的土地上,有\n一位名叫{0}的青年,职业是\n{1}...",DataManager.CharData_Instance.name,
            occCn);
    }
}

没事试试看不加密的存档文件和加密后的存档文件内容有什么不同,把DataManager.cs的Save()函数里的Text=Encrypt(Text);和Load()函数里的orginText=Decrypt(orginText);这两句代码用//注释掉是,输入名字并选择职业,点击创建按钮,退出运行,再把data.dat改后缀名为.text,然后打开内容为标准的JSON格式字符串,如下所示:

{"created":true,"name":"Jack","occupation":1}

把data.txt文件删除,并把两句代码去掉注释,重新创建相同的角色,发现data.txt打开后内容为加密后的字符串乱码

时间: 2025-01-07 03:49:03

数据存储与读取——03实例——创建游戏角色的相关文章

01- - -1.获得项目中info.plist文件的内容 2.沙盒的数据存储及读取 3.控制器view的高度和状态栏statusBar的关系 4.[UIScreen mainScreen].applicationFrame的取值 5.按钮的状态 6.错误调试技巧 7.按钮的各种状态设置

1.获得项目中info.plist文件的内容 1> [NSBundle mainBundle].infoDictionary 2> 版本号在info.plist中的key:kCFBundleVersionKey 2.沙盒的数据存储及读取 1> 数据存储: [[NSUserDefaults standardUserDefaults] setObject:version forKey:versionKey]; 存储数据时记得同步一下 [[NSUserDefaults standardUser

使用SharedPreferences进行数据存储和读取

1.储存 很多时候我们开发的软件需要向用户提供软件参数设置功能,例如我们常用的QQ,用户可以设置是否允许陌生人添加自己为好友.对于软件配置参数的保存,如果是window软件通常我们会采用ini文件进行保存,如果是j2se应用,我们会采用properties属性文件或者xml进行保存.如果是Android应用,我们最适合采用什么方式保存软件配置参数呢?Android平台给我们提供了一个SharedPreferences类,它是一个轻量级的存储类,特别适合用于保存软件配置参数.使用SharedPre

JavaFX战旗类游戏开发 第三课 创建游戏角色

在上一节课程中,我们学习了在JavaFX中绘制游戏地图.这一节课,我们将会创建我们的游戏角色. 首先,同样的,我们创建一个简单的基类. import javafx.scene.canvas.GraphicsContext; /** * 游戏物体基类 * @author Wing Mei */ public abstract class BaseObject { protected double x, y; protected double width,height; protected bool

数据存储与读取——02JSON

学习笔记适合新手,如有错误请指正.?号处也请各位指点下,谢谢. JSON是一种轻量级的数据交换和存储格式. 可用于对数据的设备(如手机的本地存储)和向Web服务器上传 并且符合面向对象编程思想 JSON数据格式 书写格式是:名称/值,如“name”,“张三” JSON基本结构: 1.对象:用{}包裹,用名称/值来表示对象中的一个属性 public class Person { public string name; public int age; public Person(string _na

ubuntu16.04修改mysql5.7的数据存储和读取的路径

1.复制mysql的基础数据到新的地址,#cp -R /var/lib/mysql/* /mnt/sdb/mysql   前面是mysql的默认数据地址,后面是需要改的地址 2.更改新地址文件夹的权限,# chown -R mysql:mysql /mnt/sdb/mysql 3.修改mysql的配置文件,使用vi修改# vi /etc/mysql/mysql.conf.d/mysqld.cnf文件,修改到新地址 4.修改mysql的启动文件,使用vi修改# vi /etc/apparmor.d

数据存储与读取——01PlayerPrefs

学习笔记适合新手,如有错误请指正.?号处也请各位指点下,谢谢. 1:PlayerPrefs是Unity自带的数据结构 2:位于UnityEngine命名空间下 3:可以对整数.浮点数.字符串3种类型的数据进行存取 4:他是持久存储在设备上的(例如:安卓,只要用户没有删除应用或者手动去清除应用数据,PlayerPrefs的数据就会一直保留) 整数的存取.读取 PlayerPrefs.SetInt("Number",num);//存储该变量 PlayerPrefs.GetInt("

【Android数据存储】SQLite使用实例(附源码)(转载)

原文地址:http://blog.csdn.net/wirelessqa/article/details/8583101 java当中提供了相当多的封装好的类来执行对SqlLite的操作,如: SQLiteDatabase 作为数据库操作的类,类似于C#当中我们自己写的helper,PS(java对此还真是高度封装) SQLiteOpenHelper 作为作为维护和管理数据库的基类实例: 会员信息管理 功能:1.查看数据库 2.清空数据库 3.增加会员 4.删除会员 5.更新会员 6.查找会员

Android 使用SharedPreferences进行数据存储和读取数据

很多时候我们开发的软件需要向用户提供软件参数设置功能,例如我们常用的QQ,用户可以设置是否允许陌生人添加自己为好友.对于软件配置参数的保存,如果是window软件通常我们会采用ini文件进行保存,如果是j2se应用,我们会采用properties属性文件或者xml进行保存.如果是Android应用,我们最适合采用什么方式保存软件配置参数呢?Android平台给我们提供了一个SharedPreferences类,它是一个轻量级的存储类,特别适合用于保存软件配置参数.使用SharedPreferen

第三章:iOS的数据存储与IO

如果应用程序值需要保存程序参数.选项相关的少量数据,则可使用NSUserDefaults进行保存; 如果应用程序只是少量数据需要保存,那使用属性列表文件就可以了; 如果应用程序有大量数据需要存储.访问,就需要借助于数据库.iOS系统内置了SQLite数据库,SQLite数据库是一个真正轻量级的数据库,他没有后台进程,整个数据库就对应于一个文件,这样就可以非常方便的在不同设备之间移植.iOS为访问SQLite数据库提供了两套API:基于C语言风格的libsqlite3.dylib和面向对象的Cor