Как хранить огромную карту тайлов?

1

Я кодирую игру на основе Java-плитки, и мне интересен лучший способ сохранить действительно большую карту плитки в базе данных. (Вся карта разделена на куски.)

Я могу хранить данные плитки как 2D-массив или массив строк (для каждого фрагмента), например:

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

где каждый номер представляет собой бетонную черепицу.

Этот подход является самым легким, но когда я использую действительно большую карту, такую как 20000x20000 плитки, она занимает неприличную массу памяти!

По моим подсчетам: если массив 20000x20000, и каждая плитка использует 3 байта (я точно не знаю, сколько пространства занимает символ в строке), то 20000 * 20000 * 3 = 1200000000 байт или 1,14 ГБ !

Думаю, это слишком много места.

Возможно, я также могу хранить данные в форме:

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

что означает 18 плиток травы, затем 3 плитки воды, затем 2 плитки из песка и так далее...

Но я думаю, что это плохой подход.

Вероятно, я могу создавать изображения для каждого фрагмента и получать из него фрагменты, но довольно сложно использовать изображения в базе данных, не так ли?

Так как я могу сделать это наиболее эффективно?

PS: Я использую массив строк, потому что я понятия не имею, как создать 2d-массив в SQL (возможно ли это?)

  • 0
    Ваш мир генерируется случайно? Потому что, за исключением очень маленьких плиток, мне действительно интересно, как вы можете создать готовый мир плиток размером 20k * 20k. И если это сгенерировано процедурно, есть лучший способ оптимизировать экономию в мире.
  • 0
    Это сгенерировано процедурно (Perlin Noise)
Теги:
database
arrays
tile

4 ответа

2

Поскольку это процедурно сгенерировано, у вас есть очень хороший способ оптимизировать ваши файлы сохранения. Вы можете сделать версию minecraft: сохранить свое семя, чтобы вам не нужно было сохранять всю карту, а затем сохранить плитки, которые были изменены после генерации каждого фрагмента карты.

Затем, когда вы загружаете, генерируете необходимые куски на основе вашего семени и применяете модификации.

0

может показаться простым, но вы можете использовать сжатие! (и уже может быть слишком поздно, хахааа)

если вы знаете, как работает сжатие Хаффмана (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

я надеюсь, что я не слишком поздно

0

Почему вы хотите загрузить все сразу? Вы разделили его на куски, чтобы не загружать все, не так ли?

0

Идея, которую у вас есть, уже хороша. Сжатие значительно уменьшит размер (даже просто кодировку длины, как и ваш пример, но другие алгоритмы, такие как zip). Если вы уже разделили данные на куски, тогда просто сжимайте каждый отдельно и разгружайте его "на лету", когда вы загружаете (и вы не будете загружать сразу все данные). Меняются ли куски? Если нет, вы можете просто работать с простым почтовым файлом вместо базы данных. Если они меняются, тогда не делайте этого, zip файлы не могут быть легко изменены.

  • 0
    Да, может быть, но карта 8000x8000 в формате PNG весит менее 2 МБ. Так что есть более эффективный алгоритм
  • 0
    64000000 символов в маленьком алфавите также не должны быть большими сжатыми текстовыми файлами. С другой стороны, если у вас нет проблем с использованием графического формата, сделайте это (я лично предпочел бы разбор текста над изображениями, но это дело вкуса)
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню