Isometrische Karte | event handler

Design Patterns, Erklärungen zu Algorithmen, Optimierung, Softwarearchitektur
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
Antworten
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Isometrische Karte | event handler

Beitrag von BeRsErKeR »

Könnte man die Raute nicht einfach als 4 rechtwinklige Dreiecke betrachten und kurz prüfen in welchem umschließenden Rechteck dieser Dreiecke die Maus liegen könnte? Das wäre ja recht simpel. Und wenn man ein mögliches umschließendes Rechteck gefunden hat, kann man ja einfach (anhand der Steigung der Hypothenuse) prüfen ob der Punkt im Teildreieck, welches zur Raute gehört, liegt. Keine Ahnung wie schnell und effektiv das wäre. Man kann aber relativ schnell alle Mauspositionen ausschließen, die außerhalb des Rechtecks liegen, welches die Raute umschließt.

Will man rausfinden, welche Raute angeklickt wurde muss man prinzipiell nur 2 mögliche Rauten prüfen. Bzw nach obigem Test, wenn die Maus eben im Teildreieck liegt, welches nicht zur Raute gehört, kann man leicht feststellen, welche Raute tatsächlich unterm Cursor liegt, nämlich die angrenzende in der jeweiligen Richtung (je nach Teildreieck 1-4).
Ohne Input kein Output.
LONy
Establishment
Beiträge: 145
Registriert: 29.09.2011, 10:04

Re: Isometrische Karte | event handler

Beitrag von LONy »

Ich stand ja bei mir genau vor dem gleichen Problem. Da ich mein Problem allerdings nicht so schön mit Vektoren usw. gelöst habe (hab das nicht ganz verstanden, bzw. war das beispiel das ich gefunden hab nur für eine diamond map geeigent) hab ich erstmal nichts dazu gesagt^^
Ich nutze bei mir eine Straggered Map... der Unterschied zur Diamond Map liegt nur darin, wie die koordinaten angeordnet sind:
http://www.pst.ifi.lmu.de/DA_Fopra/iso.gif (mit google gefunden)
Wobei ich meine Map noch etwas anders durchnummeriert habe (so wie auf dem Bild wäre sie dann doppelt so breit wie hoch). Ich denke meine Lösung ist ähnlich bzw. so wie es BeRsErKeR vorgeschlagen hat:

Ich teile die geraden Tile-Reihen (die die nicht eingerückt sind) einfach in Rechtecke auf. Jedes Rechteck teil ich nochmal in 4 Teile. Diese Teile halbier ich durch eine Gerade von Ecke zu Ecke (was meiner Tilekannte entspricht) und prüfe dann ob ich mich oberhalb oder unterhalb dieser schrägen gerade befinde. Entsprechend ob ich mich oberhalb oder unterhalb befinde, bin ich auf dem Haupttile, das von dem großen Rechteck eingeschlossen ist oder auf einem Nachbartile und korregiere dann entsprechend die berechneten Koordinaten.

Es gibt sicherlich bessere Lösungen, aber so funktionierts bei mir gut und es gibt dinge die sehr viel zeitaufwendiger sind als die Mauskoordinaten (so umständlich) von Pixelkoordinaten in Tilekoordinaten umzurechnen ;)

EDIT:
Ich hab mich für eine Straggered Map entschieden, um nicht unnötig Tiles außerhalb des Sichtbereichs rendern zu müssen. Der große Nachteil ist allerdings, dass die Koordinaten recht durcheinander sind im vergleich zur Diamond Map. In dem Forum vom ersten link hab ich gesehn, dass genau dieses Problem diskutiert wurde mit dem sichtbaren Bereich rendern.
Vielleicht steig ich auch noch irgendwann auf eine Diamond Map um, aber noch mehr Zeit will ich da erstmal nicht investieren und mal schaun wie weit ich mit meiner Straggered Map komm :D
Benutzeravatar
dot
Establishment
Beiträge: 1752
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Isometrische Karte | event handler

Beitrag von dot »

TheBenji hat geschrieben:o_x und o_y dürften ja dann wohl 0 sein, oder?
ja
TheBenji hat geschrieben:p_x unter dieser annahme auch 0 und p_y entsprechend 100?!
ja
TheBenji hat geschrieben:So, und mit den Vektoren tu ich mir schwer weil ich die nur durch Wikipedia kenne - also ich mein es ist grundlegend klar das Vektoren nur so ne Verschiebung sind und alles in allem nicht sonderlich aufregend aber mir fällt es gerade schwer das auf diesen Anwendungsfall zu projezieren...
Stell dir einen Vektor vor als Richtung im Raum. Das ist mathematisch zwar nicht wirklich korrekt, aber das ignorieren wir mal. Ich kann dir nur sehr sehr empfehlen, dass du dich zumindest mit Vektoren mal eingehend auseinandersetzt. Imo gibt es absolut keine wichtigere mathematische Grundlage für Spieleprogrammierung als Vektoren. Vektoren sind wirklich nicht schwer zu verstehen, aber wenn du sie mal verstanden hast, dann wird sooo vieles, plötzlich sooo viel einfacher, das glaubst du gar nicht ;)
TheBenji hat geschrieben:Wäre u_x dann der Punkt an dem der Mauszeiger ist gemessen an dem "schwarzen" Koordinatensystem oder was? Oo
Also quasi 100? Und u_y ebenfalls?
Falls ja (ich weiß ja das das nicht sein kann aber egal), wo ist der unterschied zu v_x/v_y?
Wie gesagt, u und v sind die Richtungen der x- und y-Achse deines Koordinatensystem. Wenn wir davon ausgehen, dass die linke schwarze Linie die y-Achse und die rechte die x-Achse ist, dann hätten u und v eben die Koordinaten:

Code: Alles auswählen

u_x = 1 / sqrt(2)
u_y = 1 / sqrt(2)

v_x =-1 / sqrt(2)
v_y = 1 / sqrt(2)
Wenn du die Werte nun in meine vorhin gepostete Formel einsetzt, wirst du sehen, dass genau das richtige rauskommt ;)
Benutzeravatar
joeydee
Establishment
Beiträge: 1224
Registriert: 23.04.2003, 15:29
Kontaktdaten:

Re: Isometrische Karte | event handler

Beitrag von joeydee »

Zur allgemeinen Verwirrung hier noch mein Lösungsweg ;-) ist im Prinzip das was dot sagt, aber vielleicht verstehst du's mit anderen Worten nochmal besser:
- du kennst den Ursprung deiner Tile-Landschaft auf dem Bildschirm (ox,oy), also da wo die erste Ecke des Tiles aus der Map (0/0) abgebildet wird.
- du kennst die X-Kante eines Tiles in Bildschirmpixeln (ux,uy) d.h. z.B. von ox/oy aus geht man ux Pixel nach rechts und uy Pixel nach unten, dann ist man am Ursprng des 2. Tiles (entspricht dem 2. Tile horizontal in der Map, also map_x=1)
- ebenso kennst du die Y-Kante auf dem Bildschirm (vx,vy) d.h. von ox/oy gehts vx Pixel nach rechts und vy nach unten, dann steht man am 2. Tile vertikal in der Map (map_y=1)

Also kannst du jederzeit Map-Koordinaten (s,t) in Bildschirm-Koordinaten umrechnen:
screen=s*u+t*v+o (u, v und o sind die oben genannten Vektoren, s und t sind Skalare, Ergebnis ist ein Vektor)
Oder in Komponenten, da dir Vektoren ja noch nicht so geläufig sind:

Code: Alles auswählen

//MapToScreen (s,t)
screenX=s*ux+t*vx+ox
screenY=s*uy+t*vy+oy
Mit diesem Wissen kannst du auch umgekehrt Screen- in Mapkoordinaten umrechnen: du hast ein Gleichungssystem mit 2 Unbekannten und musst nach s und t auflösen.

Code: Alles auswählen

//ScreenToMap (sx,sy)
s=(vx*sy-vy*sx+vy*ox-vx*oy)/(vx*uy-vy*ux);
t=(sx-s*ux-ox)/vx;
Abgerundet ergibt das dein Tile, die Nachkommastellen geben dir die relative Position im Tile.

(ob die Rechnung im Prinzip oben genannter Matrix von dot entspricht habe ich nicht überprüft; wenn aber die Ergebnisse von dot stimmen, müsste sich das 1:1 überführen lassen)

Das funktioniert übrigens für alle isometrischen Tiles, egal wie sie gestaucht, gedreht oder relativ zur Ansicht verschoben (gescrollt) sind. o, u und v definieren dabei deine aktuelle Ansicht.

Edit: noch ein Bildchen dazu gemalt.
Dateianhänge
Isotiles.jpg
Benutzeravatar
dot
Establishment
Beiträge: 1752
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Isometrische Karte | event handler

Beitrag von dot »

Nimm die Lösung von joeydee. In meiner Lösung ging ich davon aus, dass u und v normal aufeinander stehen, fällt mir grad auf...
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4318
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Isometrische Karte | event handler

Beitrag von Chromanoid »

Hier das ganze noch mal illustriert wie im JGO Thread. Sind glaube ich im Grunde die gleichen Formeln wie von joeydee, nur eben als Spezialfall.
Bild Bild
Bild
Bild

Hier dann noch mal wie man das ganze benutzt um nur die Tiles, die auf dem Screen sind zu rendern.
http://www.java-gaming.org/topics/drawi ... #msg212862
TheBenji
Establishment
Beiträge: 129
Registriert: 07.01.2011, 17:59

Re: Isometrische Karte | event handler

Beitrag von TheBenji »

Vielen vielen dank für eure ausführlichen erklärungen :)

Damit lies sich mein Problem wirklich leicht lösen und ich habe jetzt (glaube ich :D) auch schon mal die grundzüge der vektoren verstanden.

Danke das ihr euch so ne Mühe gegeben habt und es so ausführlich beschrieben habt!
Benutzeravatar
joeydee
Establishment
Beiträge: 1224
Registriert: 23.04.2003, 15:29
Kontaktdaten:

Re: Isometrische Karte | event handler

Beitrag von joeydee »

Hier noch die Ergänzung für alle die das evtl. mal nachschlagen und auf Vektorarithmetik bauen möchten:
Man baue sich eine 3x3-Matrix, in welcher die Screeninformationen stecken. Dann kann man durch einfache Multiplikation Map- in Screenkoordinaten umrechnen, bzw. mit der Inversen der Matrix von Screen- auf Mapkoordinaten.

Code: Alles auswählen

m=[
ux vx ox
uy vy oy
0   0   1
]

vScreen=vMap*m
vMap=vScreen*(m^-1)
(v in der Form [x y 1])

Antworten