X/Y Koordinaten auf Staggered Map in Spalte/Reihe umrechnen
Übersicht

Kernel32Betreff: X/Y Koordinaten auf Staggered Map in Spalte/Reihe umrechnen |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ich zerbreche mir jetzt schon seit Stunden darüber den Kopf, wie ich Mauskoordinaten (x,y) auf einer "staggered map" in Spalte / Reihe-Koordinaten umwandeln kann.
Das hier ist meine "Iso"-Map (eigentlich nur eine staggered map, bei dem jede zweite Reihe eingerückt ist): ![]() Bei einer normalen Gittermap wäre das ja einfach: Code: [AUSKLAPPEN] col% = Floor((MouseX()-gridStartX) / tileSize)
row% = Floor((MouseY()-gridStartY) / tileSize) Aber ich komme einfach nicht drauf, wie ich die X/Y Koordinaten eines Punktes auf der Map in die jeweilige Spalte und Reihe umrechnen kann. Muss man da erst mal alles in Dreiecke umwandeln oder gibt es da auch eine einfache Lösung, auf die ich noch gar nicht gekommen bin..? ![]() |
||
-------------
Wollte neulich Herrn Brot anrufen, aber da war belegt. Dann hab ich bei Wheight Watcher's angerufen, aber niemand hat abgenommen. Schliesslich hab ich im Irak angerufen, aber dort war besetzt o.O |
- Zuletzt bearbeitet von Kernel32 am Sa, Jan 10, 2009 18:52, insgesamt einmal bearbeitet
![]() |
ZaP |
![]() Antworten mit Zitat ![]() |
---|---|---|
Vielleicht hilft dir das als Denkanstoss:
0,0 ist logischerweise an 0,0 0,1 liegt genau zwischen 1,0 und 0,2, d.h. es fängt an Hälfte von 0,0 an, und endet an der Hälfte von 1,0 Das Stichwort ist Hälfte. Vielleicht kannst du es dir besser vorstellen, wenn du dir Rechtecke anstatt Rauten vorstellst. |
||
Starfare: Worklog, Website (download) |
![]() |
DAK |
![]() Antworten mit Zitat ![]() |
---|---|---|
vll hilft dir das was:
Code: [AUSKLAPPEN] For x# = 0 To 10
For y# = 0 To 10 px# = x py# = y/2 If y Mod 2 = 1 Then px#=px#+.5 Text px#*100, py#*50, x+":"+y Next Next |
||
Gewinner der 6. und der 68. BlitzCodeCompo |
Kernel32 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Nein, das hilft leider nicht.
Das Problem IST ja gerade, das alle Tiles im Grunde Rechtecke sind und sich somit ÜBERLAPPEN. Jedes Tile wird also komplett von den Rechtecken seiner vier diagonal benachbarten Tiles überdeckt -woher soll man also wissen, auf welchem Tile sich die Maus gerade befindet, wenn man z.B. nahe an der (virtuellen) Trennlinie zwischen wei Tiles klickt (denn die verläuft ja diagonal, nicht geradlinig)? ![]() |
||
-------------
Wollte neulich Herrn Brot anrufen, aber da war belegt. Dann hab ich bei Wheight Watcher's angerufen, aber niemand hat abgenommen. Schliesslich hab ich im Irak angerufen, aber dort war besetzt o.O |
![]() |
coolo |
![]() Antworten mit Zitat ![]() |
---|---|---|
Mach es doch mit der Quick/n/dirty Variante mit Imagescollide. Und damit der Speed nicht absackt, grenze den Bereich ein, den du überürüfst. | ||
http://programming-with-design.at/ <-- Der Preis ist heiß!
That's no bug, that's my project! "Eigenzitate sind nur was für Deppen" -Eigenzitat |
![]() |
HolzchopfMeisterpacker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Mach es unter keinen Umständen mit ImagesCollide ![]() Moment, ich schreib kurz n Code, wie ichs machen würde (Prinzip: Die Mauskoordinate um den Kantenwinkel der Tiles, also ca 30°, nach oben und nach rechts klappen, diese Koordinaten sind dann sozusagen auf ein horizontales Raster projiziert). N paar Minuten Geduld bitte ![]() Edit 1: Grad ganz so einfach ist mein Gedankengang nicht umzusetzen, wie ich eben feststellen musste, aber ein Ansatz wäre auch, bei jedem Tile zu Prüfen, ob abs( Tangens ) der Mauskoordinate zur oberen Ecke des Tiles => 0.5 ist. Das könnte man nämlich auch direkt beim zeichnen machen. Code: [AUSKLAPPEN] Graphics 800,600,0,2
SetBuffer BackBuffer() Global TIMER = CreateTimer(60) SeedRnd MilliSecs() Global imgTile = LoadImage( "Tile.bmp" ) MaskImage imgTile, 255,255,255 Global mx, my, mhit Global PickedTileX, PickedTileY While Not KeyDown(1) mx = MouseX() my = MouseY() PickTile(mx,my) Drawmap() WaitTimer TIMER Flip 0 Wend End ; Tilemap zeichnen Function Drawmap() Local x,y, xpos, ypos For y=0 To 4 For x=0 To 6 xpos = x *92 ypos = y *23 ; jede zweite Zeile einrücken If (y Mod 2) xpos = xpos +46 EndIf ; Tile zeichnen DrawImage imgTile, xpos, ypos Color 255,255,255 If (x=PickedTileX) And (y=PickedTileY) Color 255,0,0 Text xpos +46, ypos +23, x +"," +y, 1,1 Next Next End Function ; Über welchem Tile die Maus ist Function PickTile( px, py ) Local x,y, xpos, ypos, tg# For y=0 To 4 For x=0 To 6 xpos = x *92 ypos = y *23 ; jede zweite Zeile einrücken If (y Mod 2) xpos = xpos +46 EndIf ; Maus auf Tile? tg# = (py -ypos)/Float(px -xpos -46) If Abs(tg#)=>0.5 And (py -ypos)=>0 PickedTileX = x PickedTileY = y EndIf Next Next End Function Aber ich versuchs noch kurz weiter. |
||
Kernel32 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hm, mir sind inzwischen noch einige Methoden eingefallen, die evtl. funktionieren, aber ich habe die Hoffnung nicht aufgegeben, das es nicht doch eine "relativ" einfache und effektive Lösung gibt:
Methode 1 Das der Maus am nächsten gelegene "normale" (also nicht eingerückte) Tile finden: col% = Floor(x / tileWidth) row% = Floor(y / tileHeight)*2 Damit kann man schon mal alle "normalen" Reihen ansprechen, das Ergebnis ist ein Tile einer "nicht-versetzten" Reihe, das der Maus am nächsten liegt. Um zu testen, ob die Maus aber auf ein Tile in einer versetzten Reihe geklickt hat, müsste man dann die Distanzen zwischen Maus und Mittelpunkt des gefundenen Tiles, sowie der vier daran diagonal angrenzenden Tiles vergleichen. Das Tile mit der kürzesten Distanz zwischen Mittelpunkt und Maus ist dann eigentlich das gesuchte. Ich habe das mal eben probiert (habe hier leider kein Blitz installiert, kann das deshalb nur mit ActionScript 3.0 testen),da funktioniert es im Groben. Nur kommt es leider hin und wieder vor, das sich doch versehentlich ein Nachbartile angesprochen fühlt, obwohl gar nicht darauf geklickt wurde. Habe momentan keine Ahnung, warum ![]() Methode 2 Vielleicht würde es funktionieren, wenn man die Karte erst mal in Rechtecke zerlegt, die jeweils die Grösse eines Viertel Tiles haben: ![]() Das jeweilige Rechteck zu finden, wäre dann kein Problem. Da sich aber jeweils zwei Tiles eines dieser Rechtecke teilen, müsste man dann halt das gefundene Rechteck in zwei Dreiecke zerteilen und testen, in welchem der beiden Dreiecke sich die Maus befindet (pff... mal nach einem "point in triangle algo" kramen...). Hab's noch nicht getestet, aber könnte vielleicht funktionieren, oder? Methode 3 Nur die Eckpunkte der Tiles nehmen und mit einem "Point inside polygon"-Algo prüfen, ob die Maus sich in einem dieser Polygone befindet. Ich bin jetzt seit Stunden am Suchen und kann einfach nicht glauben, das es im ganzen Internet nicht ein einziges Beispiel dafür gibt, wie man bei einer staggered Map die Mauskoordinaten in das jeweilige Feld umwandelt. Iso-Formeln gibt es einige, aber die lassen sich ja nicht auf eine staggered Map anwenden. ![]() |
||
![]() |
HolzchopfMeisterpacker |
![]() Antworten mit Zitat ![]() |
---|---|---|
So, ich habs:
Code: [AUSKLAPPEN] ; Über welchem Tile die Maus ist
Function PickTile( px, py ) Local tg#, x, y, tx, ty ; Koordinaten transformieren x = Floor(( px +(py -23)*2 ) /92.0) ; 23 = Tilehöhe /2, 92 = Tilebreite y = Floor(( py -(px -46)*0.5 ) /46.0) ; 46 = Tilebreite /2, 46 = Tilehöhe ; Indizes transformieren tx = Floor((x-y)/2) ty = y +x ; Gepickte Koordinaten zuweisen PickedTileX = tx PickedTileY = ty End Function Zum testen einfach im Code von mir (weiter oben) mit der anderen PickTile() Funktion ersetzen. Das Tile hat die Abmasse 92 x 46 und kann hier gezogen werden. Die Schwierigkeit war übrigens die Indizes richtig zu transformieren, da die Karte ja folgendermassen Indiziert ist: Code: [AUSKLAPPEN] 3,0 2,0 2,1 1,0 1,1 2,2 0,0 0,1 1,2 1,3 .--> y=0 0,2 0,3 1,4 | X 0,4 0,5 V 0,6 Y die Transformierten Koordinaten geben nämlich die Indizes dieser Matrix zurück (Nullpunkt bei 0,0) und wie man sieht, geht die y-Mässig ins negative und x wird nur bei jedem zweiter Feld grösser. Daher die Transformation. mfG iso, koordinaten, umrechnen, position |
||
- Zuletzt bearbeitet von Holzchopf am Do, Apr 02, 2009 20:41, insgesamt einmal bearbeitet
Kernel32 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Fett! ![]() ![]() ![]() ![]() |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group