我正在编写基于Java平铺的游戏,我对在数据库中存储非常大的平铺地图的最佳方式感兴趣。 (整个地图分为几个块。)
我可以将切片数据存储为2D数组或字符串数组(对于每个块),例如:
["1100111223333",
"3130111213333",
"1300311233333",
.............................]
其中每个数字代表一个混凝土砖。
这种方法最简单,但当我使用一个非常大的地图,例如 20000x20000 图块时,它需要不雅的内存!
根据我的计算:如果数组是20000x20000,每个tile使用3个字节 (我不确切知道字符串中的字符使用了多少空间)然后20000 * 20000 * 3 = 1200000000字节或 1.14GB !
我觉得这个空间太大了。
也许我也可以以下列形式存储数据:
["G18W3S23G12W3",
["W13G3S5G12W3",
.................................]
这意味着18块草坪,然后是3块水,然后是2块沙子,等等......
但我认为这是一种糟糕的做法。
可能我可以为每个块创建图像并从中获取图块,但是在数据库中使用图像非常困难,不是吗?
那么我怎样才能最有效地做到这一点?
P.S:我使用了一个字符串数组,因为我不知道如何在SQL中创建一个二维数组(可能吗?)
答案 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
我希望我不会太迟