在Java中加载和保存基于图块的游戏。 XML还是TXT?

时间:2009-07-06 20:46:19

标签: java xml tiles

有一段时间我一直在制作一款基于2d平铺的SIM游戏,而且一切顺利!感谢这个网站和善良的人(你!),我刚刚完成了游戏的寻路部分,这太棒了!谢谢!无论如何,对于这个问题。

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

提前感谢您的帮助。

编辑: 我将尝试这里的几个想法,直到找到效果最好的那个,然后选择它作为答案。

编辑:选择xStream。简单易用!

12 个答案:

答案 0 :(得分:4)

对于基于2D平铺的游戏,XML可能有点过分。 XML适用于存储分层数据和/或标记文本,但听起来你只需要一种编码瓷砖设置的2D网格的方法,这对于普通的旧文本文件来说要容易得多。

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

SokoBean(我10年前写过的一个游戏中,不是我称之为最好的作品,而是其他什么)我用text files like this one。除了比XML更容易解析之外,您还可以使用普通的旧文本编辑器作为关卡编辑器。

答案 1 :(得分:2)

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

常见格式很常见,因为它们简单且得到很好的支持 - 您不需要编写特殊代码来解析文件(属性文件,基本上只是键值对的列表,以及xml文件 - 思考xml文件作为一种编写任意深度嵌套字典的方式)。

答案 2 :(得分:2)

如果它纯粹是基于磁贴的游戏,那么直接文本文件可能就是这样。

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

编辑:

一条重要建议:

无论你决定做什么,都要封装它!创建一个读取器接口,它接受通用输入流并返回(或填充)您的网格结构。拥有一个带有网格结构和通用输出流的编写器接口,并将数据转储到该输出流。如果你想改变你想要如何实现文件,或者你想添加网络游戏等,你会感谢你自己。

答案 3 :(得分:2)

这当然取决于您的需求,但XML格式为您提供了许多好处,我可能会在这样的项目中自己选择XML。

  • 可以自动进行 通过工具检查/验证 确定它是正确的并且根据 你设定的规则。
  • 现有Java库 解析,读取和更新XML文档。
  • 该格式可以很容易地扩展到您的程序的未来版本,但仍然很容易保持向后兼容性
  • 如果文件是XML而不是某些特别改编的文本格式,其他人可以轻松阅读和理解文件

答案 4 :(得分:2)

就你自己的东西而言,特别是游戏,XML被高估了。如果您在一家大公司工作,其他人需要查看文件的文本,那么XML 可能有意义,但即使在这种情况下,您可能会编写一个级别编辑器来执行所有操作你。

我建议您使用自己的约定使用简单的文本文件,或使用java.io.ObjectOutputStream和j ava.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分组比较split数组中的第一个值将决定你实际读取的参数。当你达到这一点时,你正在接近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,因为它很容易。

修改 这是一个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")

答案 5 :(得分:1)

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

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

答案 6 :(得分:0)

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

XML可以通过多个库轻松转换为Java POJO,因此这是一个优势。此外,您会发现它易于学习和使用,只需尝试一些教程。

但是如果您需要保存大量数据,可以考虑使用嵌入式数据库或单独的SQL Server,具体取决于您的应用程序。

答案 7 :(得分:0)

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

答案 8 :(得分:0)

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

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

答案 9 :(得分:0)

您可以考虑使用位于此处的JavaDB等嵌入式数据库: http://developers.sun.com/javadb/

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

有一些像Hibernate这样的ORM框架,您可以使用它来处理数据,但这可能对您的应用程序来说太过分了。您可以使用直接JDBC。

祝你好运并享受乐趣。

答案 10 :(得分: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>

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

答案 11 :(得分:0)

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

马亭