4

一段时间以来,我一直在制作基于 2d 瓷砖的 sim 游戏,并且进展顺利!感谢这个网站和它的好心人(你!),我刚刚完成了游戏的寻路部分,太棒了!谢谢!...无论如何,这个问题。

目前,测试级别被硬编码到游戏中。显然我需要重新处理这个。我的想法是以各种方式将我的 Game 类中的所有变量保存到文本文件中。我还可以将每个级别的详细信息写入要为一个级别加载的文件中。我的问题是,我应该只使用文本文件还是使用 XML?我基本上了解 XML 是什么,但我真的不知道如何将它与 JAVA 结合使用,或者为什么它比纯文本文件更可取。我有一点谷歌,有关于 XML 和 JAVA 的整本书!我看不出我需要了解如何使用 XML 和 JAVA 来完成这项工作,但我确实需要知道的比我做的更多。

提前感谢您对此的帮助。

编辑:我将在这里尝试几个想法,直到找到最有效的想法,然后将其选为答案。

编辑:选择 xStream。轻松简单!

4

12 回答 12

4

对于基于 2D 瓦片的游戏,XML 可能是多余的。XML 非常适合存储分层数据和/或标记文本,但听起来您只需要一种编码 2D 平铺设置网格的方法,这对于普通的旧文本文件来说要容易得多。

只需让每一行都是一排瓷砖,然后决定每个瓷砖需要多少个字符(可能一两个就可以了)。然后决定如何用文本文件中的字符来表示 2D 世界中的对象。

SokoBean(我在 10 多年前编写的游戏,所以不是我称之为我最好的作品,但无论如何)我使用了像这样的文本文件。除了比 XML 更容易解析之外,您还可以使用普通的旧文本编辑器作为关卡编辑器。

于 2009-07-06T20:58:52.867 回答
2

您将文件用于内部目的。简短的回答是,只要文件格式符合您的目的,就可以了。你确实想尽你所能来确保格式清晰、尽可能简单和可扩展。这里最重要的一点是将读取和写入的数据提取到代码中负责读取和写入文件格式的单个点。

常见格式很常见,因为它们简单且支持良好 - 您无需编写特殊代码来解析文件(属性文件,基本上只是键值对列表和 xml 文件 - 将 xml 文件视为编写任意深度嵌套字典的方式)。

于 2009-07-06T20:54:29.257 回答
2

如果它纯粹是基于图块的游戏,那么纯文本文件可能是要走的路。

您可能需要固定宽度的整数,每行后用换行符用空格分隔。易于阅读且易于解析,无需 XML 库。

编辑:

一个重要的建议:

无论你决定做什么,封装它!制作一个读取器接口,该接口接受通用输入流并返回(或填充)您的网格结构。有一个写入器接口,它采用网格结构和通用输出流并将数据转储到该输出流。如果您改变了对如何实现文件的想法,或者如果您想添加网络播放等,您稍后会感谢自己。

于 2009-07-06T20:54:57.663 回答
2

当然,这取决于您的需求,但是 XML 格式给您带来了很多好处,在这样的项目中我自己可能会选择 XML。

  • 它可以通过工具自动检查/验证,以确保它正确并符合您设置的规则。
  • 现有的 Java 库可以解析、读取和更新 XML 文档。
  • 该格式很容易为您的程序的未来版本扩展,但仍然很容易保持向后兼容性
  • 如果它们是 XML 而不是一些特别适应的文本格式,其他人很容易阅读和理解您的文件
于 2009-07-06T20:55:59.283 回答
2

就您自己的东西,尤其是游戏而言,XML 被高估了。如果您在一家大公司工作,其他人需要查看您的文件的文本,那么 XML可能是有意义的,但即使在这种情况下,您也可能会编写一个可以为您完成所有工作的关卡编辑器。

我建议使用您自己的约定的简单文本文件,或者使用java.io.ObjectOutputStreamand java.io.ObjectInputStream将数据直接写入数据文件(如果您有很多信息或对象)或java.util.Properties写入数据(如果您只需要写原语)。

上面的很多人都提到 XML 有多好,因为它具有“自动序列化”,但我真的认为在 Java 中工作时不值得一提,因为我上面列出的两种方法也是自动的,但在更高级等级。

另外不要忘记,使用 XML 标记表示 2D 瓦片地图非常不直观,而在字符文件中逐行写入它们相当容易读写。

前任。)

WWWWWWWWWW  
WSWWWWW EW  
W W K WW W  
W W   WW W  
W WW WWWDW  
W  X     W  
WWWWWWWWWW  

你可以像上面那样做,哪里W是墙,哪里是S开始,哪里是E出口,哪里K是钥匙,哪里是D门,哪里是X怪物。一切都在哪里以及应该如何设置关卡非常明显,即使是文本文件也是如此。

我在许多专业游戏项目中使用过文本文件。事实上,我只在为某人完成合同工作时才使用 XML,因为 XML 看起来“更专业”,尽管在大多数情况下使用它是不必要的,而且只是浪费空间,使事情变得过于复杂。

另一个例子:

SpawnFrequency 0.1 20.5
HealthPoints 5
Stats 12 500 30 10 11  

你可以想象任何其他可能发生的事情。然后,当您将文件读入 Java 时,只需使用BufferedReader.readLine()获取每个参数,然后String.split()获取该参数的所有值的数组。然后,比较拆分数组中的第一个值的大型 switch 语句或 if/else 分组将确定您实际读取的参数。当您达到这一点时,您就接近了 XML 的用处,但是对于这种用途,它仍然可能过于臃肿。然而,XML 可以帮助解释其中一些神秘的值可能是什么:

XML中的上述内容:

或者可能是这样的:

`<GuyStuff>`  
    `<SpawnFrequencyMinimum>0.1</SpawnFrequencyMinimum>`  
    `<SpawnFrequencyMaximum>20.5</SpawnFrequencyMaximum>`  
    `<Health>5</Health>`  
    `<Strength>12</Strength>`  
    `<Agility>500</Agility>`  
    `<Stamina>30</Stamina>`  
    `<TechnoWizardry>10</TechnoWizardry>`  
    `<JavaSkillz>11</JavaSkillz>`  
`</GuyStuff>`  

但是,当您再次开始遇到这种复杂性时,您不妨开始使用java.io.Serializable它,因为它非常简单。

编辑 这是一个可序列化的示例。

public class MySaveData implements java.io.Serializable //Serializable doesn't need any methods implemented, it simply says, "hey Java, my object can be written to a file."
{
    float data1;
    int data2;
    Object data3;
    //BufferedImage data4; //Note that in order for an object to serialize, it can't contain any data members that are not Serializable, so this would be illegal.
}

import java.io.*;
public class DataReader
{
    public void saveData(File loc, MySaveData obj1, MySaveData obj2, MySaveData obj3)
    {
        try
        {
            //You can use any type of OutputStream to create an OOS, so you can for
            //example use one when you're connected with Sockets or something similar.
            ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(loc));

            //Writing objects is tremendously easy, and so are primitives.
            //Note that the order you write them in is the same order you will read them.
            os.writeObject(obj1);
            os.writeObject(obj2);
            os.writeObject(obj3);
            os.writeDouble(someValueINeededToWrite);
            os.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public void loadData(File loc, PlaceToPutData place)
    {
        try
        {
            //ObjectInputStream follows the same rules as OOS mentioned above.
            ObjectInputStream is = new ObjectInputStream(new FileInputStream(loc));

            //Remember to read your data back the same order you wrote it.
            place.obj1 = is.readObject();
            place.obj2 = is.readObject();
            //If you don't want one of the objects for some reason and want
            //to get something after it, you can just read the next one but not use it.
            readObject();
            place.value = is.readDouble();
            is.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

通常,您的文件将是这样的:new java.io.File("/Documents/MyGame/MyDataFile.whateverIFeelLikeAsLongAsItsConsistent").

于 2009-07-06T23:01:54.973 回答
1

如果您在一个对象(例如 HashMap,或者您自己设计的对象)中有游戏状态,那么您可以使用 XStream 将其写为 XML 文件然后再次使用 XStream 将其读回新对象.

有一个两分钟的教程向您展示如何序列化/反序列化。它可以毫无困难地处理大多数对象——您不需要实现或指定任何特定的接口。你也不需要 JAXP、SAX、DOM 等。

于 2009-07-06T21:20:08.097 回答
0

这取决于您需要保存多少数据,以及您需要如何检索它。

XML 可以很容易地转换为带有多个库的 java POJO,因此这是一个优势。此外,您会发现它易于学习和使用,只需尝试一些教程即可。

但是如果你需要保存大量数据,你可以考虑使用嵌入式数据库,或者单独的 sql server,这取决于你的应用程序。

于 2009-07-06T20:54:07.917 回答
0

如果您是唯一要修改文件的人,请使用您想要的任何格式。但是,如果您希望用户或测试人员或其他人修改它,请使用 XML。XML 的一大优势是它是一种标准格式,很多人(甚至很多非程序员)都知道如何编写代码。

于 2009-07-06T21:32:08.043 回答
0

如果我需要 XML 生态系统的某些部分,我只考虑使用 XML:验证、转换、自动序列化/反序列化等。但我知道所有这些东西是什么,并且我知道如何使用它们来达到很好的效果。

如果你不这样做——从这个问题的主旨来看,我猜你不这样做——那么真正的问题是“我应该学习所有这些东西,以便将我的信息保存在 XML 文档中吗?” 答案是“你几乎肯定不应该”。

于 2009-07-06T21:40:18.820 回答
0

您可能会考虑使用像 JavaDB 这样的嵌入式数据库,位于:http: //developers.sun.com/javadb/

嵌入它只有 2.5MB,您可能会发现以结构化、可靠的方式保存各种数据的能力非常有用。

有像 Hibernate 这样的 ORM 框架,您可以使用它来处理数据,但这对您的应用程序来说可能是多余的。您可以改用直接的 JDBC。

祝你好运,玩得开心。

于 2009-07-06T23:28:28.040 回答
0

作弊有问题吗?如果是这样,那么无论输出以某种方式,我都会加密。如果不是,那么只需以纯文本形式输出。

就格式而言,我会使用 XML。你可以做类似的事情

<Map>
    <Tile x="1" y="1" value="2"></Tile>
    <Tile x="1" y="2" value="1"></Tile>
    <Tile x="1" y="3" value="7"></Tile>
    ...
</Map>

这将提供一个很好的可读格式,并且可以存储相当多的数据。

于 2009-07-08T03:18:45.173 回答
0

我使用一个类(实现 java.io.Serializable)来存储游戏统计信息。然后我使用 ObjectOutputSteam 将该类写入文件。要加载该类,您可以使用 ObjectInputStream。

马汀

于 2009-09-09T10:49:12.963 回答