Iso Tile Map
lima-city → Forum → Programmiersprachen → C/C++ und D
angabe
anwenden
armee
art
code
empire
entsprechenden position
gegner
hilfe
idee
karte
koordinate
monat
position
problem
produzieren
raute
sitzen
spiel
tasten
-
Hallo, liebe Community:
ich habe leider ein Problem, dass ich wohl nicht ohne Hilfe lösen kann :(
Ich bin seit nun fast 2 Monaten an einem Multiplayer Strategiespiel. Funktioniert echt leichter als ich gedacht hätte. Innerhalb dieser 2 Monate hab ich mit einem Freund ein 2D Spiel erstellen können, bei dem man Gebäude bauen und Armeen Produzieren kann. Die KI des Gegners hat auch schon recht gut funktioniert. Alles auf quadratischen Flächen. Dadurch habe ich natürlich nicht diesen 3D Effekt, wie spiele, wie Age of Empire. Genau das möchte ich jetzt ändern. nicht so schwer dachte ich mir. Ich muss ja einfach nur andere arten von Bildern ausgeben und fertig. Nun, falsch gedacht. Es fehlt ja auch noch die "Maus-positionsabfrage"....
Zurzeit habe ich auf einem x=0 bis x = 1024 && y=0 bis y = 576 einfach einen Grashintergrund.
Mit meiner Isozeichnen Funktion zeichne ich dann auf der entsprechenden position meine Raute.
(mit isozeichnen((tasten->x*50),(int)(tasten->y*25),50);)
Ich muss also die x Position ausrechnen. Die Frage ist nur: wie?
Zur Zeit besteht mein Sourcecode für die x und y Position aus:
return iX / 50;
und
return iY / 25;
Jemand eine Idee? In einem Tutorial wurde es versucht mit sin(120*) und cos(120*) gelöst. Der Sourcecode hat bei mir aber leider nicht funktioniert :(
Weitere Angaben:
Die Breite der Raute ist 50px
Die Höhe der Raute ist 25px
Wenn niemand eine Idee hat müsste ich jedes mal den Pythagoras zwischen den beiden restlichen Rauten anwenden :( -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Hallo raubritta,
Was für eine Art von Karte verwendest du? Eine Rauten oder eine Flatterrand-Karte
Bei einer Rautenkarte ist es einfacher. Bsp. Code für Rautenkarte:
w =50 //Breite h = 25 //Höhe w2 = w / 2 //halbe Breite h2 = h / 2 //halbe Höhe for (x = 0 ; x < 100 ; x++) for (y = 0; y < 100; y++) { xpos = w2*( x - y ) - w2; ypos = h2*( x + y ); Blit( xpos, ypos, tile[ x ][ y ] ); }
Um den X bzw. Y-Wert zu bekommen musst du die Umkehrformel der grafischen Ausgabe berechnen, das bekommt man durch Auflösen der Gleichung nach x und y heraus.
int x = (mouseX / tileWidth + mouseY / tileHeight); int y = (mouseY / tileHeight - mouseX / tileWidth);
ich hoffe ich konnte dir weiterhelfen und viel Erfolg mit deinem Projekt.
Gruß x-web -
Hey x-web:
vielen Dank für deine Antwort. Das sieht schonmal recht gut aus. Was bitte ist eine Flatterrand-Karte.
Ich habe so eine Karte:
http://raubritta.lima-city.de/tileskizze.jpg
Ich habe deinen Code zwar noch nicht verstanden aber werde auf jedenfall ausprobieren, deinen Code zu Implementieren.
(Blit soll wahrscheinlich das Zeichnen des Tiles sein oder?)
danke noch mal
Beitrag zuletzt geändert: 4.2.2009 21:19:37 von raubritta -
Hallo,
du willst eine isometrische Perspektive?
Also die Idee ist ja, dass eine Iso-Tile-Map aus einer normalen Tile-Map hervorgeht, indem man sie um 45° dreht und dann die y-Achse skaliert.
Das ganze würde folgende Matrix erledigen:
a ist der Skalierungsfaktor, z. B. 0.5
Man kann jetzt auf ein Koordinatenpaar (x, y) einfach die Inverse dieser Matrix anwenden, also eine Matrix, die zuerst die Skalierung rückgängig macht und dann um -45° dreht:
Da wir mit Integern rechnen, müssen wir die Werte durch einen Bruch annähern. z. B.
diese neuen Koordinaten x_2, y_2 dann noch in deine alte Funktion stecken:x_2 = (7*x)/10 + (14*y)/10; y_2 = -(7*x)/10 + (14*y)/10;
und du bekommst die Nummer des Tiles. Wobei die Nummerierung dann etwas komisch ist, und du z. B. negative Tile-Nummern bekommst, aber das ist relativ einfach wieder gerade zu biegen.return x_2 / 50; return y_2 / 25;
Beitrag zuletzt geändert: 5.2.2009 0:28:20 von calexus -
So, ich beginne mal mit deiner Lösung calexus.
Leider ist auch hier noch ein Mathematischer Fehler dabei. Richtig ist:
links oben in der ecke liegt die Position 0 / 0...
links unten ist die Position x = 16 y = 31
rechts oben ist die Position x = 14 y = -27
rechts unten ist die Position x = 29 y = 3
und du bekommst die Nummer des Tiles. Wobei die Nummerierung dann etwas komisch ist, und du z. B. negative Tile-Nummern bekommst, aber das ist relativ einfach wieder gerade zu biegen.
Die frage ist nur wie. Also als leicht sehe ich das leider nicht an :(
vielen dank.
@x-web:
int x = (mouseX / tileWidth + mouseY / tileHeight);
int y = (mouseY / tileHeight - mouseX / tileWidth);
wenn ich mit dem x wert nur nach links gehe wird ganz rechts 20 angezeigt. Also ganz richtig. ABER wenn ich runter gehe wird meine x-Position immer größer. Das dürfte doch nicht sein oder?
Irgendwas mach ich noch falsch :(
aber weiterhin vielen Dank für eure Hilfe...
-
Mein Code läuft letztlich auf selbe hinaus, was x-web geschrieben hat. Bei mir ist noch der Faktor Wurzel 2 drin (damit die Skalierung erhalten bleibt).
Von dem was du geschrieben hast, und von deiner Skizze kann ich mir leider noch nicht so ganz vorstellen, was du als Endergebnis haben willst. Wenn du nochmal eine genaue Skizze mit Pixelangaben und Tile-Nummern machst, könnte ich es dir programmieren.
Die allersimpelste Lösung wäre (wie du dir ws auch schon überlegt hast) ein Lookup-Tabelle, wo du für jeden Pixel die Tile-Nummer speicherst. Klingt bisschen kompliziert, hat aber abgesehen vom Speicherplatz nur Vorteile
- sehr schnell
- Änderungen machen keine Probleme
- wirklich exakt (besonders an den kritischen Stellen, wie den Rändern der Tiles).
du könntest die Lookup-Tabelle realisieren als 8-Bit-Bild in einem sehr einfachem Dateiformat, wie http://en.wikipedia.org/wiki/PCX oder Netpbm und das mit GIMP bearbeiten (die Tilemap zeichnen und jedem Tile eine andere Farbe geben). -
Ich habe jetzt immer weiter versucht durch ausprobieren die Formel zu vervollständigen. Soweit bin ich durch eure Hilfe gekommen:
xposition: return ((iX + iY)/25)-(iY/25); yposition: return (((iX*2-iY*2)/50)-((iY/25)*(-2))-(iX/25))*2; In meiner Zeichnenfunktion: if(tasten->y < 576) { if(tasten->x % 2 == 0) // gerade (0,2,4...) { if(tasten->y % 2 == 0) { isozeichnen((int)(tasten->x*25),(int)(tasten->y*12),50); } else { isozeichnen((int)(tasten->x*25),(int)(tasten->y*12),50); } } else { if(tasten->y % 2 == 0) { isozeichnen((int)(tasten->x*25),(int)(tasten->y*12),50); } else { isozeichnen((int)(tasten->x*25),(int)(tasten->y*12),50); } } }
Was hat es mir gebracht:
die X Koordinate geht ganz normal von 0 bis 44, wie sie es sollte. Auch meine Y Koordinate landet am ende im 40 bereich. Das problem ist nur: ich kann NUR gerade Koordinaten anzeigen.
Ich habe fast alles menschenmögliche ausprobiert. (unteranderem natürlich versucht das "*2" wegzulassen. Somit werden aber leider die hälfte der Koordinaten übersprungen.
(es ist richtig deprimierend an so einer einfachen Formel 2 Wochen zu sitzen. Dabei könnte ich schon längst beim Gebäudebauen ect. sein ...)
ich bitte um Hilfe Sad
Beitrag zuletzt geändert: 9.2.2009 16:22:29 von raubritta -
also mein Angebot steht noch: Mach doch mal eine gescheite Skizze, dann kann ich es dir programmieren.
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage