# Isometric-Tiled-Map: Spielfeld mit Höhenunterschieden



## data89 (21. Jan 2010)

Hallo zusammen,

ich möchte ein Spielfeld nach dem Schema "isometric tile map" bauen und mache mir gerade Gedanken über die Mathematik hinter dem ganzen Kram. Ein einfaches tile entsteht, indem man ein Quadrat um 45 Grad dreht und auf die Hälfte der Höhe staucht! 

Nur wie komme ich auf so eine "Formel" bei den Höhenunterschieden? Hier ein Beispiel:





Bzw. wie macht man das generell mit den Höhenunterschieden?

Ich bin dankbar für Eure Tipps!
data89


----------



## Marco13 (21. Jan 2010)

Erinnert mich erstmal an http://www.java-forum.org/spiele-multimedia-programmierung/84152-2d-map-hoehenunterschieden.html ...


----------



## data89 (21. Jan 2010)

Hab' ich auch gelesen, aber ich finde, dass es nicht so richtig passt. Widelands bzw. der Vorschlag bezieht sich ja auf mehr als 4-Eckige "Figuren". Ich will das Ganze zwar auch in Java2D realisieren, aber nur mit 4-Ecken pro tile.

Ich will das halt wie "Open Transport Tycoon Deluxe" realisieren!


----------



## tuxedo (22. Jan 2010)

Na soviel anders ist der Ansatz nicht. Im verlinkten Thread braucht man 3-ecke um die "Figuren" darzustellen. Bei deinen 4-eckigen Tiles kommt man, wenn man es so wie in TTD macht auch nicht um 3-Ecke drum rum. Nur ist da halt die Anordnung etwas "geordneter".

- Alex


----------



## Steev (22. Jan 2010)

Hi,

ich habe mal etwas ähnliches gemacht: Da bin ich allerdings den Ansatz mit ISO-Grafiken gegangen, weil das so ziemlich die schnellste Art ist, etwas zu rendern. Höhenunterschiede sind dann auch ziemlich einfach, weil man dann einfach nur die Höhe von der Screen-Y-Koordinate abziehen muss. Das einzige was dann etwas getrickse ist, ist die Tiefensortierung. Aber auch das ist kein Problem, wenn man ein Tilebasierte Objekthaltung verwendet. Allein bei den Rändern einer Ebene muss man etwas tricksen. Ich mache das mitlerweile so, dass ich dort einfach eine Eckgrafik verwende, die "unter" dem eigendlichen tile liegt. Das bedeutet aber auch, dass meine maximale Höhe nicht größer als die Grafik sein darf. Das hatte mir aber da nichts ausgemacht.

http://www.java-forum.org/spiele-multimedia-programmierung/90151-performancetest-iso-editor.html


----------



## data89 (24. Jan 2010)

Welche Anforderungen werden denn an eine Engine gestellt? Die übernimmt ja das Rendern (Höhen & Tiefen) des Spielfeldes und verwaltet die "Rohdaten" aus denen das Spielfeld erzeugt wird. Übernimmt somit Repaint und auch teilweises Repaint von einzelnen Tiles. Außerdem sorgt sie ja dafür, dass alles Scrollbar ist (ich habe nicht die gesamte Welt auf dem Bildschirm).

@Steev:
Wie zeichnest Du in Deinem Map-Editor die Tiles? Hast Du z.B. ein JPanel, wo Du die paint-Methode überschreibst, oder wie machst Du das?

data89


----------



## Steev (24. Jan 2010)

Das Zeichnen in meinem Map-Editor wird über die Render-Logik meiner Engine übernommen. Letztendlich läuft das ganze in ein VolatileImage und wird dann zum Beispiel in ein JPanel gezeichnet. In dem Editor verwende ich derzeit ein JPanel. Das ganze geht aber natürlich auch mit JFrame usw.

Die Datenhaltung der Map bzw. das Rendern der Tiles geht dann denkbar einfach von statten. Jedes Tile ist ein eigenes Objekt, dessen Adresse zusammen mit der Höhe und einigen anderen Daten in dem Map-Array gespeichert wird. In der Klasse Tile gibt es dann eine Rendermethode, die von der Tilemap aufgerufen wird und die entsprechende Daten, wie die Position usw. an die Rendermethode des Tiles übergibt. In der Rendermethode wird dann nichts anderes gemacht, als die Position zu errechnen und da das entsprechende Bild hinzuzeichnen.


----------



## data89 (24. Jan 2010)

Danke Steev, so ähnlich hatte ich mir das gedacht ... ich habe aber noch eine Detailfrage: In der rechten (oder war's die linke?) oberen Bildschirmecke zeigst Du die FPS an. Wie kommst Du auf diesen Wert?

Generell habe ich mir jetzt einiges an Anforderungen überlegt und mir auch schon ein Demo-Szenario ausgedacht um ein kleines Spielchen zu schreiben ... ich kann's ja mal im Forum hier veröffentlichen ... dauert aber noch nen' Moment ;-)

Was mir jetzt noch ein bisschen Kopfschmerzen bereitet: woher bekomme ich Bilder für mein Demo-Szenario? Mit Inkscape kann ich die ja schlecht machen. Die müssen ja alle in dieser 45-Grad-Ansicht gezeigt (zumindest Häuser und rechteckige Gegenstände) werden und Blender ist mir zu kompliziert ...

data89


----------



## Steev (24. Jan 2010)

Die FPS-Rate sowie die UPS-Rate lasse ich mir von meiner Engine zurückgeben. Diese macht im Grunde genommen nur eine Zeitmesseung vor der Renderung sowie nach der Renderung, dann wird einfach eine Sekunde durch die aktuelle Renderzeit (Nanosekunden) gerechnet. Das was rauskommt ist die aktuelle Frame-Rate.
Dasselbe mache ich auch im Logik-Thread.

In diesem Zusammenhang verwende ich natürlich noch einen FrameLimiter, damit die Framerate auf allen Rechnern ungefähr gleich gut läuft. Auf älteren Rechnern sollte (normalerweise) Frameskipping verwendet werden.

Mit den Grafiken kann ich dich nicht beruhigen: Ich habe meine Grafiken alle von Hand per PhotoFiltré gepixelt und mir die Grundmodelle per Google-SketchUp erstellt, wo es auch eine ISO-Ansicht gibt.
Das Grafische feintuning habe ich dann mit GIMP oder Fireworks gemacht.


----------



## data89 (25. Jan 2010)

Könntest Du die Stichwörter "FrameLimiter" und "Frameskipping" nochmals ausführen?

Außerdem: es sind 30-Grad in der Ansicht!


----------



## Steev (25. Jan 2010)

Der FrameLimiter ist eigendlich dazu da, dass auf besonders guten Rechnern die Frame-Rate nicht ins Bodenlose steigt, sondern möglichst auf allen Systemen gleich funktioniert. Dabei wird im Grunde genommen anhand der aktuellen FrameRate und der maximalen gewünschten Frame-Rate ermittelt, ob der aktuelle Rechner schneller oder langsamer rendert. Wenn der Rechner schneller rendert, so wird ein entsprechend langes sleep hinter jedem Rendervorgang durchgeführt, damit die maximal eingestellte FrameRate nicht überschritten wird (in meinem Programm verwende ich 59 FPS).
FrameSkipping kommt dann zu Einsatz, wenn der Rechner es nicht schafft, zum Beispiel meine 59 Bilder in einer Sekunde zu Rendern. Dann werden einfach einige Renderungsschritte übersprungen. Das hat den Vorteil, dass zum Beispiel eine Animation auf einem langsamen Rechner genauso schnell abläuft wie auf einem schnellen Rechner. Das Problem dabei ist halt, das durch das überspringen der Bilder einfach ein Teil eines Ablaufes fehlt. Dadurch kommt der berühmte Ruckeleffekt zu stande. Würde kein FrameSkipping verwendet. So währe das Spiel auf einem langsamen Rechner zwar flüssiger, aber dafür würde jede Animation um einiges langsamer funktionieren als auf einem schnelleren Rechner.
Das sind beides im Grunde genommen ganz simple Sachen.

PS: Es sind eigendlich ∼26,6◦ (genauer: arctan(0.5)) statt 30°, weil das besser aussieht. (Es ergibt dann genau ein Pixelmuster 2 X-Pixeln und einem Y-Pixel - also so ein Treppenmuster)

Gruß
Steev


----------



## data89 (25. Jan 2010)

Vielen Dank für Deine Ausführungen, Steev!

Aber ich weiß garnicht, wie ich "FrameLimiter" und "Frameskipping" implementieren soll ... Könntest Du mir vielleicht den Source-Code Deines ISOEditors posten oder per PN schicken? Das wäre echt toll ... dann könnte ich mir mal ansehen, wie Du das mit dem FrameLimiter, FrameSkipping und der Paint-Logik implementiert hast.

data89


----------



## Steev (25. Jan 2010)

Hi,

mit dem Source-Code wirst du wahrscheinlich nichts anfangen können da, wie gesagt, hinter der gesamten Renderung meine Engine steht. Da die Engine weitesgehend generisch ist, ist der Quellcode auch recht schwer zu verstehen.

Bei Code and Coke gab es mal ein Tutorial wo das - glaube ich - auch angeschnitten wurde.

Space Invaders 102 - Timing and Animation in Java

Gruß
Steev


----------

