【问题标题】:How to store huge tile map?如何存储巨大的瓦片地图?
【发布时间】:2015-11-12 06:41:25
【问题描述】:

我正在编写一个基于 Java 磁贴的游戏,我对在数据库中存储一个非常大的磁贴地图的最佳方式很感兴趣。 (整个地图被分成了块。)

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

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

每个数字代表一个具体的瓷砖。

这种方法最简单,但是当我使用非常大的地图(例如 20000x20000 瓦片)时,会占用大量内存!

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

我觉得空间太大了。

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

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

这意味着 18 格草然后 3 格水然后 2 格沙等等......

但我认为这是一个糟糕的方法。

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

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

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

【问题讨论】:

  • 你的世界是随机生成的吗?因为除了非常小的瓷砖,我真的很想知道如何设计一个 20k*20k 瓷砖的预建世界。如果它是程序生成的,那么还有一些更好的方法可以优化世界拯救。
  • 它是程序生成的(柏林噪声)

标签: java sql arrays database tile


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    为什么要一次加载所有内容?您已将其分成块,不必加载所有内容,不是吗?

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 是的,也许可以,但是 png 格式的 8000x8000 地图的权重小于 2MB。所以有一些更有效的算法
      • 小字母表中的 64000000 个字符也不应该是一个大的压缩文本文件。另一方面,如果您在使用图像格式方面没有问题,那就去吧(我个人更喜欢解析文本而不是图像,但这只是个人喜好问题)
      • @user3696488:苹果和橙子。 PNG 使用 两个 优化:一个 Line Difference 过滤器 (PNG Spec: 6. Filter Algorithms),这使得 LZW compression 的东西(甚至)更可压缩。
      【解决方案4】:

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

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

      一旦您知道 Java 已经可以为您做到这一点,这是我的简单方法...

      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
      

      我希望我一点也不晚

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多