Benutzer mit den meisten Antworten
Bitmap Positionierung anhand von Koordinaten

Frage
-
Hallo Leute,
ich habe derzeitig ein Problem damit in meinem Radar die Karte von einem Spiel dem Spieler richtig anzuordnen, so dass die Karte in richtiger Position zu dem Spieler ist.
Ich habe mal ein paar Bilder davon gemacht um es besser zu Veranschaulichen:
Dies hier ist die "Minimap" von dem Spiel wo alles richtig ist, in der Mitte der Pfeil ist der Spieler und dieser blickt gerade in die Richtung Nord-Östlich.
Hier ist das Bild von meinem Radar, leider sieht man hier auf dem ersten blick, dass die Positionierung von dem Spieler (Blau) nicht mit der von der Minimap vom Spiel übereinstimmt.
Hier erstmal meine derzeitigen Code versuche um das gerade zu biegen:
Also: wenn die Funktion aufgerufen wird, benutzt er zu 90% immer die else if Schleife die mit //2 Makiert ist, in dieser Schleife habe ich den Code von //1 Benutzt um die obrigen Bilder zu machen, da dies von den 4 if Schleifen die ist, die am nächsten an das gewünschte Ergebniss kommt.private static Bitmap DrawMinimapOverlay(Bitmap img, Bitmap RadBit) { Graphics G = Graphics.FromImage(RadBit); int cellBindpointX = (int)((((Math.Abs(ObjectMgr.LocalPlayer.X) % TILE_SCALE_FACTOR) / TILE_SCALE_FACTOR) * ZoomFactor) * 1); int cellBindpointY = (int)((((Math.Abs(ObjectMgr.LocalPlayer.Y) % TILE_SCALE_FACTOR) / TILE_SCALE_FACTOR) * ZoomFactor) * 1); if (ObjectMgr.LocalPlayer.X <= 0 && ObjectMgr.LocalPlayer.Y <= 0) {//2 G.DrawImage(img, ((int)((RadarWidth) / 2) - cellBindpointX) - 1 * ZoomFactor, ((int)((RadarHeight) / 2) - cellBindpointY) - 1 * ZoomFactor); } else if (ObjectMgr.LocalPlayer.X >= 0 && ObjectMgr.LocalPlayer.Y <= 0) { G.DrawImage(img, ((int)((RadarWidth) / 2) + (cellBindpointX - ZoomFactor)) - 1 * ZoomFactor, ((int)((RadarHeight) / 2) - cellBindpointY) - 1 * ZoomFactor); } else if (ObjectMgr.LocalPlayer.X <= 0 && ObjectMgr.LocalPlayer.Y >= 0) { G.DrawImage(img, ((int)((RadarWidth) / 2) - cellBindpointX) - 1 * ZoomFactor, ((int)((RadarHeight) / 2) + (cellBindpointY - ZoomFactor)) - 1 * ZoomFactor); } else if (ObjectMgr.LocalPlayer.X >= 0 && ObjectMgr.LocalPlayer.Y >= 0)//2 { G.DrawImage(img, ((int)((RadarWidth) / 2) + (cellBindpointX - ZoomFactor)) - 1 * ZoomFactor, ((int)((RadarHeight) / 2) + (cellBindpointY - ZoomFactor)) - 1 * ZoomFactor); } return img; }
Falls noch irgendwas unklar sein sollte, bitte hier Schreiben, werde die benötigten Daten dann nachliefern.
Antworten
-
Hallo Palin,
ich habe nun gewiss 2-3 Stunden da dranne gesessen und habe die Fehler nun alle behoben bekommen, das erste Problem mit der Minimap wurde gelöst in dem ich bei der Y Position -20 gemacht habe, somit habe ich mir das Positionieren des Spielers usw. erspart und alles passt.
Dann ist mir ein Problem mit der Positionierung der Spieler aufgefallen, dieses habe ich behoben mit der Zoom Größe, die auf 2 stand und halt mit den Coordinaten Multipiziert wurde und dann falsche Positionen zeichnete.
- Als Antwort markiert Super_Günther Montag, 26. November 2012 07:36
Alle Antworten
-
Hallo Günter,
ich gehe jetzt mal davon aus das die Bildmitte der Ursprung des Koordinaten-Systems ist.
Wenn der Spiele die x,y-Koordinaten = 0, hat sollte er in der Bildmitte erscheinen.
Du verschiebst ihn dann aber nochmal um deinen Zoomfaktor.
Mir ist auch nicht klar wie so der Wert sich in den einzelnen Achsen-Abschnitte ändert.
Ich denke folgender Code sollte es tun, wenn die Bildmitte der Koordinaten Ursprung ist.
private static Bitmap DrawMinimapOverlay(Bitmap img, Bitmap RadBit) { Graphics G = Graphics.FromImage(RadBit); int cellBindpointX = (int)((((Math.Abs(ObjectMgr.LocalPlayer.X) % TILE_SCALE_FACTOR) / TILE_SCALE_FACTOR) * ZoomFactor) * 1); int cellBindpointY = (int)((((Math.Abs(ObjectMgr.LocalPlayer.Y) % TILE_SCALE_FACTOR) / TILE_SCALE_FACTOR) * ZoomFactor) * 1); Point BildMitte = new Point ((int)((RadarWidth) / 2, (int)((RadarHeight) / 2) G.DrawImage(img, (BildMitte .X + cellBindpointX , (BildMitte .Y + cellBindpointY ); return img; }
Ich hab es jetzt aber nicht getestet.
MFG
Björn
-
Hi Günter,
ein Punkt noch bei der Berechnung des cellBindPoint, ich weiß jetzt nicht genau was der TILE_SCALE_FACTOR ist.
Aber ich denke, der cellBindPoint sollte eher so Berechnet werden.
int cellBindpointX = (int)((((ObjectMgr.LocalPlayer.X) * TILE_SCALE_FACTOR) * ZoomFactor) );
Ist jetzt auch nicht getestet.
MFG
Björn
-
Hallo Björn,
danke für deine Antwort, aber leider bringt auch sie nicht das gewünschte Ergebnis.
Hier mal die Bilder davon:
Spiel Minimap:
Radar:
Hier mal noch ein paar Daten:
static int RadarHeight = 300; static int RadarWidth = 300; const int TILE_HEIGHT = 256; const float TILE_SCALE_FACTOR = 533.5F;
Also, das cellbindx+y ist definitiv richtig, weil dieses wird auch Benutzt um die Richtigen Karten zu finden, und allein daran weiß ich, dass es auf jedenfall Funktionstüchtig ist.
Was ich vergessen habe zu Erwähnen heute Mittag ist, dass ich hier 4 kleine Bilder Lade die dann die Karte im Hintergrund Bilden, daher kommt es nun dazu das jetzt mit dem Code von dir nur ein Bild Angezeigt wird, nur was mich etwas verwirrt ist, dass der Code der normal die 4 Bilder lädt normal in einer anderen Funktion ist und mit dieser Positionierungsfunktion wenig am Hut hat.
Aber das dieses Puzzle mal Vollständig wird, Poste ich diesen hier auch noch zur Sicherheit.
public static Bitmap GetNearbyMinimap() { Bitmap Minimap = new Bitmap(TILE_HEIGHT * 3, TILE_HEIGHT * 3); Graphics G = Graphics.FromImage(Minimap); float mapSize = 34133.333f; // 34133.333 float tileSize = 150.0f / 36.0f * 8 * 16; // 533.333 float absCoordX = (mapSize / 2) - ObjectMgr.LocalPlayer.X + tileSize; float absCoordY = (mapSize / 2) - ObjectMgr.LocalPlayer.Y + tileSize; int b = (int)(absCoordX / tileSize) - 1; int a = (int)(absCoordY / tileSize) - 1; if (OldMinimap.Equals(new MinimapData(a, b, ZoomFactorx))) { return (Bitmap)OldMinimap.img.Clone(); } OldMinimap.a = a; OldMinimap.b = b; OldMinimap.zoom = ZoomFactor; // Minimap = AddTile(Minimap, a, b, (int)0, (int)0, TILE_HEIGHT); var count = 0; for (int aa = a - 1; aa <= a + 1; aa++) { for (int bb = b - 1; bb <= b + 1; bb++) { Minimap = AddTile(Minimap, aa, bb, TILE_HEIGHT + (TILE_HEIGHT * (aa - a)), TILE_HEIGHT + (TILE_HEIGHT * (bb - b)), TILE_HEIGHT); count++; } } Bitmap FinalMM = new Bitmap((int)(ZoomFactor * 3), (int)(ZoomFactor * 3)); Graphics G2 = Graphics.FromImage(FinalMM); G2.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed; G2.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low; G2.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed; G2.DrawImage(Minimap, 0, 0, ZoomFactor * 3, ZoomFactor * 3); OldMinimap.img = (Bitmap)FinalMM.Clone(); return FinalMM; }
Die Code womit ich letzt endlich die Minimap auf das Radar zeichne:
DrawMinimapOverlay(GetNearbyMinimap(), Minimap);
Hoffe wir kommen nun ein Stückchen weiter ;)
-
Hi Günter,
ich war jetzt davon ausgegangen, dass du den Spieler (Variable img) in die Karte Zeichnen willst (RadBit). Wie es jetzt aus sieht hast du eine größere Karte in img die du passend unter das Radar schieben willst.
Das sieht ganz oben eigentlich recht gut aus.
Da ist dann eher das Problem, dass der Blaue Punkt nicht in der Mitte ist.
Das setzen wird wohl in einer Anderen Methode geschehen.
Wenn es das nicht sein sollte, beantworte bitte die gestellten Fragen und bedenke das man nicht weiß was du Programmierst und was hinter deinen Variablen steckt.MFG
Björn
-
Hallo Björn,
Die Variablen die hierzu notwendig sind habe ich im 2. Post von mir mit rein gepackt, sollte dort irgendwas fehlen, dann bitte bescheid geben.
In der Tat wird die Karte nicht Richtig dem Blauen Punkt positioniert, das ist auch der Grund warum ich diesen Thread eröffnet habe, weil ich dort im Moment nicht weiter komme.
Soweit ich weiß wird diese Positionierung in der Funktion
DrawMinimapOverlay
vorgenommen, somit habe ich diese auch im ersten Post mit bei gepackt, da dies der knackpunkt sein wird um das Problem zu beheben.
Gruß Günther
Edit: oben/links ist der 0 Punkt von der 300x300 Picturebox.- Bearbeitet Super_Günther Freitag, 16. November 2012 00:48
-
Hi Günter,
du hast immer noch nicht beantwortet welches Koordinaten-System du verwendest.
Und wenn du mir angibst, dass TILE_SCALE_FACTOR = 533.5F ist, kenne ich zwar den Wert, aber weiß immer noch nicht welche Bedeutung hinter der Variabel Steckt.
Was den Blauen Punkt angeht, für mich sieht es so aus das in der Funktion die Karte und nicht der Punkt gesetzt wird. Ich weiß aber wirklich nicht was in der Variabel img übergeben wird.
Das solltest du Wissen, wenn nicht, Speicher das Bild einfach mal auf die Festplatte und schau was dir dort übergeben wird.
MFG
Björn
-
Hallo Björn,
Die Variable TILE_SCALE_FACTOR = 533.5F ist im grunde das selbe wie
float tileSize = 150.0f / 36.0f * 8 * 16; // 533.333
Wie man hier entnehmen kann bestimmt dieser Wert, die größe von einer Kachel der Minimap, wo von ich 4 Stück lade um sie auf dem Radar zu Zeichnen.
Du hast genau richtig gedacht damit das diese Funktion die Karten Position bestimmt und nicht den Blauen Punkt, ist auch alles so gewollt. (Hier in diesem Thema geht es auch darum, dass die Karte nicht richtig unter den Blauen Punkt gesetzt wird)
Zu der Variable img:
private static Bitmap DrawMinimapOverlay(Bitmap img, Bitmap RadBit)
img ist in diesem Falle die Minimap, welche ein Bitmap ist, worauf die 4 Kacheln gezeichnet werden, und da img gezeichnet werden soll ist am Ende der Funktion return img;.
Gruß Günther
-
Hi Günter,
danke für die Infos jetzt sehe ich ein Wenig klarer.
Wenn du dir den Blauen Punkt anschaust siehst du das er nicht mittig im Bild ist sondern nach oben verschoben ist.
Diese Verschiebung musst du auch auf das Bild anwenden.
(Oder den Punkt mittig Zeichnen ;) )
MFG
Björn
-
Naja wird bestimmt nicht so einfach sein, die Positionierung zu ändern da ja viel von dem Blauen Punkt aus geht wie z.B. andere Spieler oder Gegenstände.
Werde da mal so ab 20Uhr bei schauen, wenn ich Schwierigkeiten bekomme, werde ich mich nochmal melden, auch wenns geklappt hat, um das Endergebnis zu präsentieren ;)
-
Die Position des Spielers sollst du auch nicht ändern.
Nur das Zeichnern der Position auf der Radar Karte.
Das Bild was du hier Erzeugst, wird Wahrscheinlich in einem der nächsten Schritte, an einer andere Methode übergeben die dann den Spieler(Blauer Punkt) einzeichnet.
-
So nach einer Stunde ist der Übeltäter gefunden welches die Karte falsch eingezeichnet hat, es war TILE_SCALE_FACTOR was ich nun zu diesem geändert habe: const float TILE_SCALE_FACTOR = 150.0f / 36.0f * 8 * 16;
nun sieht die Positionierung so aus:
Wie dort zu sehen ist, stimmt die Positionierung nun überein, jedoch gibts halt immer noch ein Problem und zwar wenn ich mich von dor aus nach Norden drehe und ein paar Meter mich hoch bewege verschiebt sich die Minimap (Die Bildgrafik unter den Spielern) nicht korrekt, ich denke das sie sich genau um 90° in die falsche Richtung bewegt.
Hier ein Bild davon:
Ich bin mir derzeitg nicht sicher wie ich dies beheben kann, aber ich denke diese Minimap bewegung nur aus der Funktionist DrawMinimapOverlay() ist.
Wäre für ein paar Ideen dankbar :)
-
Danke Björn, das war die Lösung ;)
Hier mal ein Bild von der Lösung:
Also da ich ja ein Perfektionist bin, hast du noch eine Idee wie ich es noch ein wenig genauer machen kann?
Oder liegt dieses Problem nun an dem Zoomfactor, der evtl. zu hoch eingestellt ist?
Gruß Günther
-
Hallo Palin,
ich habe nun gewiss 2-3 Stunden da dranne gesessen und habe die Fehler nun alle behoben bekommen, das erste Problem mit der Minimap wurde gelöst in dem ich bei der Y Position -20 gemacht habe, somit habe ich mir das Positionieren des Spielers usw. erspart und alles passt.
Dann ist mir ein Problem mit der Positionierung der Spieler aufgefallen, dieses habe ich behoben mit der Zoom Größe, die auf 2 stand und halt mit den Coordinaten Multipiziert wurde und dann falsche Positionen zeichnete.
- Als Antwort markiert Super_Günther Montag, 26. November 2012 07:36