2016-03-29 8 views
1

Ich habe eine Klasse, in der ich das Terrain der Welt meines Spiels speichern. Die Spielwelt besteht aus Würfeln und jeder Würfel hat ein Terrain. Die Information wird als ziemlich großes 3D-Array von ganzen Zahlen gespeichert.Konstruktor überschreitet die 65535 Bytes Grenze

Das Problem, auf das ich jetzt stoße, ist, dass meine 'Karte' zu groß ist, um in einer Klasse (oder enum) zu speichern. Da ich außerhalb von Klassen und Enums nichts wirklich weiß, weiß ich nicht, was ich damit machen soll.

Soll ich eine tekst Datei daraus machen und das lesen? Wenn ja, wie mache ich das? Eine andere Lösung wäre, die Karte über mehrere Klassen oder Enums aufzuteilen und sie dann zur Laufzeit wieder zusammenzuführen, aber ich weiß auch nicht, wie das geht, und es scheint eine ziemlich schlechte Lösung zu sein.

EDIT: Dies ist Teil der Weltkarte:

0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 
0 0 0 0 0 0 0 0 0 2 2 0 0 0 1 1 1 1 1 1 
0 0 0 0 0 0 0 0 0 2 2 0 0 0 1 1 1 1 1 1 
0 0 0 0 0 0 0 0 0 2 2 2 2 1 1 1 1 1 1 1 
0 0 0 0 1 0 0 0 0 2 2 2 2 1 1 1 1 1 1 1 
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 
0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 1 1 1 1 
0 0 0 0 0 0 0 1 0 1 0 0 1 0 1 1 1 1 0 0 
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 
0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 
0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 0 0 0 
0 0 1 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 
0 0 1 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 
0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 1 
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 
0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 1 1 1 0 0 
0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 1 0 0 
0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 

Es gibt 40 von diesen Blöcken (38 so mehr) und jeder repräsentiert die Welt an einem bestimmten z-Koordinate. Ich habe das auch im Arrayformat. Es wäre toll, wenn Sie einen (Beispiel-) Code zur Verfügung stellen könnten, wie Sie das aus einer Datei lesen können.

+0

Ich schlage vor, dass Sie teilen es nicht in verschiedene Klassen auf, speichern Sie es einfach in einer Datei. – Maljam

+0

Versuchen Sie einen Speicherabbildungsansatz, und lesen Sie den Speicher in Abschnitten nach Bedarf. – Jay

+3

Anstatt das Array als Literale im Code zu definieren, könnten Sie die Daten in einer Datei speichern und von der Festplatte lesen, um sie in das Array zu bekommen. – Jire

Antwort

1

Es ist viel besser, es in Ressource zu setzen. Erstellen Sie einfach eine Textdatei neben Ihrer Klasse (zB map.txt genannt), setzen Sie dort Ihre Weltkarte im gleichen Format, das Sie in der Frage verwendet haben, dann laden Sie den Code wie folgt verwendet:

public int[][][] loadMap() { 
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(getClass() 
      .getResourceAsStream("map.txt"), StandardCharsets.ISO_8859_1))) { 

     List<int[][]> result = new ArrayList<>(); 
     List<int[]> cur = new ArrayList<>(); 
     String line; 
     while((line = reader.readLine()) != null) { 
      line = line.trim(); 
      if(line.isEmpty() && !cur.isEmpty()) { 
       result.add(cur.toArray(new int[0][])); 
       cur.clear(); 
      } else { 
       String[] cells = line.split("\\s+"); 
       int[] row = new int[cells.length]; 
       for(int i=0; i<cells.length; i++) row[i] = Integer.parseInt(cells[i]); 
       cur.add(row); 
      } 
     } 
     if(!cur.isEmpty()) 
      result.add(cur.toArray(new int[0][])); 
     return result.toArray(new int[0][][]); 
    } catch (IOException e) { 
     throw new UncheckedIOException(e); 
    } 
} 
+0

Danke, das ist was ich brauchte. – Sander

0

Können Sie Ihren Fehler anzeigen?

Wenn Sie dont alle Ihre Karte geladen werden Sie Ihre Karte durch Stücke teilen kann, und in einem Xml zum Beispiel, wie dies alle Ihre Karte speichern:

<map> 
    <chunk x=0 y=0> 
     <!--chunk informations> 
    </chunk> 
    <chunk x=0 y=1> 
     <!--chunk informations> 
    </chunk> 
    <!--other chunks> 
</map> 
+0

Ich brauche das Ganze, um die Welt zu initialisieren. Und es wäre viel einfacher, die gesamte Welt auf einmal zugänglich zu machen. Aber trotzdem: Ich weiß nicht, wie man Informationen aus einer anderen Datei lädt. – Sander

+1

Das sollte ein Kommentar sein, keine Antwort. – bhspencer

+0

Siehe auch https://docs.oracle.com/javase/7/docs/api/java/nio/MappedByteBuffer.html – Jay

1

Wenn es möglich ist, in der Use Case könnten Sie stattdessen Blöcke von byte[] oder sogar short[] verwenden. Dann sollten Sie innerhalb der 65535 Byte-Grenze gut sein.

size för byte[] : 20 x 20 x 40 x 1 = 16000 bytes 
size för short[]: 20 x 20 x 40 x 2 = 32000 bytes 
+0

könnte dies eine Lösung für meine kleineren Karten sein, aber sie gehen bis zu 80x80x80 = 512 000, so dass es für die größeren Karten immer noch ein Problem wäre. – Sander

Verwandte Themen