如何存储巨大的瓷砖地图?

时间:2014-06-02 12:11:07

标签: java sql arrays database tile

我正在编写基于Java平铺的游戏,我对在数据库中存储非常大的平铺地图的最佳方式感兴趣。 (整个地图分为几个块。)

我可以将切片数据存储为2D数组或字符串数​​组(对于每个块),例如:

["1100111223333",
 "3130111213333",
 "1300311233333",
 .............................]

其中每个数字代表一个混凝土砖。

这种方法最简单,但当我使用一个非常大的地图,例如 20000x20000 图块时,它需要不雅的内存!

根据我的计算:如果数组是20000x20000,每个tile使用3个字节 (我不确切知道字符串中的字符使用了多少空间)然后20000 * 20000 * 3 = 1200000000字节或 1.14GB

我觉得这个空间太大了。

也许我也可以以下列形式存储数据:

["G18W3S23G12W3",
["W13G3S5G12W3",
.................................]

这意味着18块草坪,然后是3块水,然后是2块沙子,等等......

但我认为这是一种糟糕的做法。

可能我可以为每个块创建图像并从中获取图块,但是在数据库中使用图像非常困难,不是吗?

那么我怎样才能最有效地做到这一点?

P.S:我使用了一个字符串数组,因为我不知道如何在SQL中创建一个二维数组(可能吗?)

4 个答案:

答案 0 :(得分:2)

因为它是程序生成的,所以您有一种非常好的方法来优化您的保存文件。 您可以执行Minecraft版本:保存种子,这样您就不必保存整个地图,然后保存在生成​​地图的每个块之后修改的切片。

然后在加载时,根据种子生成所需的块,并应用修改。

答案 1 :(得分:0)

为什么要一次加载所有内容?你已经把它分成几块而不必加载所有东西,不是吗?

答案 2 :(得分:0)

你的想法已经很好了。压缩会大大减小大小(即使只是像你的例子一样的游程编码,但其他算法,如zip更多)。如果您已经将数据分成块,那么只需单独压缩每个数据并在加载时即时解压缩(并且您不会一次加载所有数据,是吗)。块会改变吗?如果没有,您可以只使用普通的zip文件而不是数据库。如果他们确实改变了,那就不要这样做了,zip文件不能轻易改变。

答案 3 :(得分:0)

可能听起来很简单,但你可以使用压缩! (已经太晚了,hahhaaa)

如果您知道Huffman压缩的工作方式(http://en.wikipedia.org/wiki/Huffman_coding),您会发现存储空间可能会大幅缩小......

一旦你知道Java CAN ALREADY为你做这个,这是我的简单方法......

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;


public class Abc {

    public static void main(String[] args) {
        new Abc().doIt();
    }

    private void doIt() {

        try {
            //create a big Object (well my string might not be big)
            String veryBigObject = new String("have a class that implements serializable, like String") ;
            File file = new File("myFile.bin");

            //write it as zipped stream into a file
            ObjectOutputStream oos = new ObjectOutputStream(new GZIPOutputStream(new FileOutputStream(file) ) );
            oos.writeObject(veryBigObject);
            oos.close();

            //read it back again
            ObjectInputStream ois = new ObjectInputStream(new GZIPInputStream(new FileInputStream(file) ) );
            String loadedInstance = (String)ois.readObject();
            ois.close();
            System.out.println(loadedInstance);

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

然后这是输出:

have a class that implements serializable, like String

我希望我不会太迟