Isometrische Karte | event handler
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
Re: Isometrische Karte | event handler
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).
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.
Re: Isometrische Karte | event handler
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
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
- dot
- Establishment
- Beiträge: 1752
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: Isometrische Karte | event handler
jaTheBenji hat geschrieben:o_x und o_y dürften ja dann wohl 0 sein, oder?
jaTheBenji hat geschrieben:p_x unter dieser annahme auch 0 und p_y entsprechend 100?!
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: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...
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: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?
Code: Alles auswählen
u_x = 1 / sqrt(2)
u_y = 1 / sqrt(2)
v_x =-1 / sqrt(2)
v_y = 1 / sqrt(2)
Re: Isometrische Karte | event handler
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:
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.
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.
- 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+oyCode: 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;(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.
- dot
- Establishment
- Beiträge: 1752
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: Isometrische Karte | event handler
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...
- Chromanoid
- Moderator
- Beiträge: 4318
- Registriert: 16.10.2002, 19:39
- Echter Name: Christian Kulenkampff
- Wohnort: Lüneburg
Re: Isometrische Karte | event handler
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.



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
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
Re: Isometrische Karte | event handler
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!
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!
Re: Isometrische Karte | event handler
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.
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])