Sehr große Tile Map schnell u. mit geringem Speicherverbrauch anzeigen?

karl-alfons

Grünschnabel
Hi,

ich bin nun schon seit langen auf der Lösung für ein Problem. Konnte nirgends eine Lösung oder Idee finden die mich weiter gebracht hätte. Vielleicht findet sich ja hier jemand der mir helfen kann?

Das Problem:
Ich möchte eine Karte erstellen mit hexagonalen Feldern, änlich einem Siedler-Spiel. D.h. ich habe nur ca. 10 verschiedene Hexagone, die sollen aber mehrfach (auch schon 100000 mal) gezeichnet /angezeigt werden. Die Karte soll dann aber auch mit der Maus verschiebar und mit dem Mausrad skalierbar sein. Ich habe nun zwei Methoden ausprobiert (komm ich gleich zu) und jede hat einen Nachteil, den ich nicht akzeptieren kann und suche nun nach der Lösung diese zu beheben.

1. Methode:
Ich zeichne alle meine Hexfelder in ein BufferedImage, welches ich vorher erzeugt habe und lasse es dann anzeigen. Danach kann ich es sehr schnell bewegen und skalieren. Jedoch ist der Speicherverbrauch enorm, da er ja das ganze Bild im Speicher halten muss. Hier müsste ich irgendwie den Speicherverbrauch in den Griff bekommen.

2. Methode:
Ich zeichne in einer for-Schleife die Felder einzeln, nacheinander, direkt auf den Monitor. Dauert natürlich bei großen Karten ewig (auch hier wären ja 1,2 Sekunden schon zu lange, wenn man die Karte nur ein Feld weiter nach links schieben will, bzw. skalieren will. Aber es dauert eh viel länger). Der Speicherverbrauch ist allerdings akzeptabel.

Ich weiß nicht ob ich was übersehen habe, ob es vielleicht gar nicht funktionieren kann, ob die Idee nichts taugt oder sonst was. Falls ihr noch was braucht an Infos, reiche ich die gerne nach...

Vielen Dank schon mal

Gruß
 
Wie stellst du dir das Skallieren vor? Wie weit darfst du zoomen? Unbegrenzt?
Ansonsten könntest du immer nur gewisse Bereiche buffern (meinetwegen 10x10 Tiles). So kannst du, solltest du eine größere Sicht brauchen die entsprechenen Felder nachladen. So wird es ja auch normal in Games gemacht, es werden immer Abschnitte nachgeladen (siehe Gothic etc.).
 
...danke schon mal für die schnelle Antwort.

Es ist so gedacht, dass das Skalieren eine Übersicht über die Karte bieten soll. D.h. wie ne Weltkarte beim Atlas (siehe Bild) und da wär es ja schon gut wenn man möglichst viele Felder zu sehen bekommt, soweit sie noch von einander unterscheidbar sind.
Der Vorschlag nur begrenzte Bereiche zu buffern denke ich fällt damit aus, bzw. macht nur Sinn, wenn ich nicht zoomen würde und man nur "wenige" Felder zu Gesicht bekäme. Das habe ich auch schon probiert, hilft beim Zoomen aber leider wenig, fürs verschieben (ohne Zoom) ist es ne Idee....

Zum Bild: sind jetzt 10 Inseln, aber sollen so zwischen 50-100 letztendlich werden (plus natürlich das mehr an Wasserfeldern, was dann dazu kommen würde).
 

Anhänge

  • karte.jpg
    karte.jpg
    30,9 KB · Aufrufe: 354
Benutzt du plain Java oder eine Engine dazu?

Was soll denn die Weltkarte können? Bewegt sich darauf etwas? Normal sind Weltkarten nur ein Bild welches die TiledMap darstellt ohne dabei selber auf das Tiled-System zuzugeriefen (eben wie ein großes Photo).
Und wieso fällt der Bereichsbuffer raus? Das habe ich noch nicht verstanden.
 
Benutze keine Engine. Dachte das wäre nicht nötig. Meinst du man sollte Eine verwenden? Habe allerdings noch keine Erfahrung mit so was.

Die Karte muss nichts können, sie soll nur zur Orientierung der Spieler dienen (Das ganze soll ein PBEM werden, hatte ich noch gar nicht erwähnt). Es sollen noch Koordinaten und Namen für die Landregionen eingetragen werden. Vielleicht, irgendwann in ferner Zukunft, kommen noch kleine Bildchen wie Schife oder Einheiten hinzu. Das Ganze soll aber statisch bleiben und nur ein Bild des momentanen Zustands wiedergeben.
D.h. du hast schon recht mit der Weltkarte. Wenn ich das Ganze als ein Bild darstellen könnte, wie in Methode 1 beschrieben, ohne das es so viel Speicher verbrauchte, wäre ich glücklich.

Vielleicht habe ich das mit dem Buffern falsch verstanden. Meinst du ich soll z.B. 10x10 Felder zusammenfassen und quasi als eins darstellen (also z.B. ein BufferdImage dafür erstellen) und dann wenn diese 10x10 Felder ins Sichtfeld rücken anzeigen lassen? Würde ja aber auch heissen, dass ich alle 10x10 Felder zeichnen müsste (und diese auch alle neu, das sie ja nun kleiner dargestellt werden), wenn ich die ganze Karte im Zoommodus zeigen will. Und vom Speicher her würde sich doch auch nichts ändern, oder?
Vielleicht musst du mir das auch noch mal erklären, wenn ich da jetzt nicht richtig liege.

Skalieren tu ich übrigens mit der Graphics2d-Methode scale(). Vielleicht ist das ja auch nicht das Gelbe vom Ei? Schien mir aber am einfachsten.

Wie schätzt du das denn ein, ist es denn möglich mit Java so etwas überhaupt in der Größenordnung hinzubekommen? Kenne ähnliche Tools die mit C/C++ geschrieben sind und meine Karten schnell anzeigen und einlesen können, mit sehr wenig Speicherverbrauch. (Deshalb dachte ich, mit Java sollte das auch kein Problem sein...)

Gruß
 
Also die Sache ist die, ich bin der Meinung dass die Bildverarbeitung von java sehr schnell sehr langsam und resourcenfressend sein kann, wenn man nicht aufpasst.
Aber ein einziges Bild (für die Wletkarte) ist doch nicht das Problem. Einfach ein Standartbild (du solltest ja wissen wie deine Welt aussieht) und dann meinetwegen ein Paar Pfeile für Positioen drauf und fertig ist die Weltkarte, wenn keine Interaktione möglich sein soll.
Das mit den 10x10 Feldern war nur ein Beispiel. Dein bildschrim kann 10x10 Tiles darstellen. Das heißt du musst auch nur 10x10 darstellen und nicht mehr. Wenn du jetzt diene Kamera bewegst lädst du einfach den zweiten 10x10-Block und zeigst diesen zusätzlich an (so können maximal 4 10x10 Blöcke im Speicher liegen). Beim zoomen ist das natürlich nicht so einfach. Hier handlest du es allerdings ähnlich. Wenn du rauszoomst fültt eine 10x10 Block den Bildschirm nicht mehr aus, also musst du so viele 10x10 Blöcke wie nötig laden (deswegen auch die Frage nach der Zoomdimension).
Wenn du diesen Weg nutzt sparst du einiges an Speicher, was für die Darstellung von nicht sichtbaren Grafiken von Nöten wäre.

Allgemein würde ich bei so einem großen Projekt shcon an ein Framework a lá Slick oder LWJGL verweisen. Beides nutzt OpenGL und damit kann man eben direkt zeichnen. Allerdings muss man sich da erst reinfinden (wie überall) und so schnell wirst du da nicht zu deinem gewünschten Spiel kommen. Slick bietet zwar Möglichkeiten eine spezielle TiledMap (nach speziellem Format) direkt zu laden (Editor dafür steht auch bereit), aber du musst dich um die Kamera usw selbst kümmern. Und kann wiederum Wissen im Bezug auf OpenGL nützlich sein ;)


Allgemein ist Java mit der Zeit immer shcneller geworden und brauch sich bei Berechnungen und GUI nicht mehr hinter C++ und sonstigem verstecken (ASM mal aussen vor gelassen). Aber wenn es darum geht viele Grafiken darzustellen, gerätst du sehr schnell an Grenzen (meine Meinung(!)), natürlich kannst du da auch Optimierarbeit leisten.
 
Ok, das mit dem Standardbild habe ich ja versucht. Ich habe ein BufferedImage erstellt, in der Größe die ich brauchte und habe dann dort die Felder reingezeichnet. Allerdings ist hier das Problem, dass ich nicht beliebig große BI erstellen kann, da der Speicher die Grenzen setzt und ich auch keine Applikation haben will, die 1,5 gig RAM verbraucht. Die Bilder sind also immer riesig und ich habe keine Ahnung wie/ob man die kleiner bekommen kann.

Was ich auch schon probiert habe, aber das hat auch nur für kleinere Bilder funktioniert, ist das Ganze zu speichern, dass man beim Laden des Karten-Viewers nur einmal ein Bild laden muß und dann dies durch die Gegend schiebt und scaliert, aber die gespeicherten Bilder sind auch immer ziemlich groß gewesen, also z.B. 200-500 mb. Ich kann mir gut vorstellen, dass ich da irgendwo Fehler gemacht habe aber ich weiß nicht wo...

Also wenn du ne Idee hast, wie man ein relativ kleines Bild (also speichertechnisch klein) aus den vielen Feldern machen kann wäre das super. Vielleicht hast du ja auch noch ein paar Tips wo ich sowas nachlesen kann?

Ja und was Slick und OpenGL angeht, kannst du da was zum Lesen empfehlen, damit ich da mal reinschnuppern kann? Wo ist da eigentlich dann der Unterschied, wenn ich OpenGL verwende, anstatt Java2D, hier sind doch auch viele Funktionen, wenn man drauf achtet, Hardware beschleunigt, oder bezieht sich das nicht auf die Grafikkarte?

Naja, aber wenn das zu dem Gewünschten Karten-Viewer führt, dann arbeite ich mich auch da rein. Ist ja immerhin ein Hobby, dem ich gerne nachgehe. Man lernt ja auch noch einiges dabei.


Gruß
 
Zurück