【发布时间】:2013-11-15 21:15:59
【问题描述】:
我正在制作一个基于文本的游戏的控制台应用程序,我需要保存诸如 HP 和 Money 之类的值,以便以后能够检索它们。
我尝试过使用设置,但问题是它们依赖于文件名和文件路径,这意味着如果其中一个更改,则不会加载整个保存(这是一个问题,因为大多数玩家会更改文件名)。
所以我希望能够将变量的所有值保存到一个文本文件中并在以后检索它们。
有没有可能有效地做这样的事情?
如果有人可以提供帮助,谢谢。
【问题讨论】:
我正在制作一个基于文本的游戏的控制台应用程序,我需要保存诸如 HP 和 Money 之类的值,以便以后能够检索它们。
我尝试过使用设置,但问题是它们依赖于文件名和文件路径,这意味着如果其中一个更改,则不会加载整个保存(这是一个问题,因为大多数玩家会更改文件名)。
所以我希望能够将变量的所有值保存到一个文本文件中并在以后检索它们。
有没有可能有效地做这样的事情?
如果有人可以提供帮助,谢谢。
【问题讨论】:
您可以使用 IO 命名空间提供的简单类进行文件操作。
在这里你可以找到很多例子
但总而言之,我建议遵循这个伪代码
让我们从第一个任务开始
string folder = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
string folder = Path.Combine(folder, "myappNameDataFolder");
Directory.CreateDirectory(folder);
string dataFile = Path.Combine(folder, "myappNameDataFile");
这里我们尝试在windows保留的特殊文件夹中建立一个文件夹,用于这台计算机的所有用户共有的应用程序数据。请参阅枚举 Environment.SpecialFolder。这是存储值的最佳位置,因为您拥有在那里读/写文件的所有正确权限。
现在您可以使用通用 StreamWriter 类在该文件夹中创建文件
using(StreamWriter sw = new StreamWriter(dataFile, true))
{
....
在上面的语句中,StreamWriter 是在 using 块内创建的,以确保它在封闭块的末尾关闭和销毁。
现在您可以构建缓冲区来存储变量。这里我只展示了一个变量,我想这些变量在代码的这一点是可用的
StringBuilder sb = new StringBuilder();
sb.Append("HP=" + valueForHPToSave.ToString();
.... other variables follow this line
将缓冲区写入流并关闭并释放流
sw.Write(sb.ToString());
}
逆运算(在应用启动时读回值)只需使用 StreamReader、ReadAllLines 并在等号处拆分每一行以恢复原始值
另一种方法是使用框架提供的内置serialization mechanism。
在这种情况下,您将构建一个名为 AppState 的类,并使用 Serializable 属性对其进行标记
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable()]
public class AppState
{
public int HPValue {get; set;}
.... other variables to store/read from the serialization stream
}
目的是从磁盘写入和加载此类的实例,在磁盘中存储恢复应用程序状态所需的所有变量。
现在您可以在主类中声明AppState 类的全局实例,并在应用执行期间开始存储这些值。
public class Program
{
public static AppState stateVariables = new AppState();
public static void Main()
{
// read back the values of stateVariables here... (see later)
...
stateVariables.HPValue = 100;
...
}
}
当应用程序关闭时,您可以使用这样的代码编写类的实例
string folder = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
string folder = Path.Combine(folder, "myappNameDataFolder");
Directory.CreateDirectory(folder);
string dataFile = Path.Combine(folder, "myappNameDataFile");
using(Stream stateStream = File.Create(dataFile))
{
BinaryFormatter serializer = new BinaryFormatter();
serializer.Serialize(stateStream, stateVariables);
}
当应用程序启动时,您使用类似的方法读回这些值
public class Program
{
public static AppState stateVariables = new AppState();
public static void Main()
{
string folder = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
string folder = Path.Combine(folder, "myappNameDataFolder");
Directory.CreateDirectory(folder);
string dataFile = Path.Combine(folder, "myappNameDataFile");
if (File.Exists(dataFile))
{
using(Stream stateStream = File.OpenRead(dataFile))
{
BinaryFormatter deserializer = new BinaryFormatter();
stateVariables = (AppState)deserializer.Deserialize(stateStream);
}
}
}
}
请注意我没有测试过这段代码,要完全理解,请阅读更多关于Serialization on MSDN的信息
【讨论】:
一种选择是保存到“我的文档”中的文件(或子文件夹中的文件)中。
获取路径 - Environment.GetFolderPath 和 MyDocuments
var root = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
var fileName = Path.Combine(root, "MyGame.sav");
比以任何你喜欢的方式读/写你的设置。
您也可以考虑使用其他文件夹,例如LocalApplicationData...
【讨论】: