Problem mit versetztem Koordinatenursprung
Übersicht

![]() |
SkabusBetreff: Problem mit versetztem Koordinatenursprung |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo!
Ich bin gerade auf ein Problem gestoßen was ich nicht ganz lösen kann und hoffe das von euch jemand vielleicht ne Lösung kennt. Mein Problem ist folgendes: Ich habe nun für mein 2D-RPG-Projekt Spielersteuerung und Tilemap bereits erfolgreich programmiert und auch die Kolision mit unbegehbaren Tiles habe ich bereits nach einigem Probieren ordentlich programmiert. Nun habe ich aber ein Problem meine Spielergrafik an meine Kollision anzupassen. Die Tiles sind 16x16 Pixel groß, die Spielergrafik ist 24x32 groß (Alles an dem Rpgmakerstandard angelehnt) Die Tilekollision funktioniert nach genauer Koordinatenberechnung. Leider finde ich keine Möglichkeit die Spielergrafik so zu versetzen das sich die die Kollision immer an der jeweilgen Kante der grafik orientiert in welche Richtung der Spieler geht.Das Programm erkennt die Kollision logischerweise erst wenn die 0,0 Koordinate des Rechtsecks der Grafik an der jeweiligen Position ist und erkennt dann erst eine Kollision. Weiß jemand wie ich den Koordinatenursprung der Grafik ändern kann? Hier noch mein momentaner Code, fals jemand den durchsehen möchte: ACMain: Code: [AUSKLAPPEN] ;Include-Dateien Include "ACHeader.bb" ;Programminitialisierung Graphics 320,240,16,1 ;Initialisierung des Grafikmodus SetBuffer BackBuffer() ;Stellt die Ausgabe auf BackBuffer ;Laden der Grafiken testtile = LoadAnimImage("source\tiles\test.bmp",16,16,0,48) testchar = LoadAnimImage("source\chars\test.bmp",24,32,0,96) ;Die Hauptschleife, wird beendet sobald leaveGame = 1 ist While leaveGame = 0 ClsColor 0,255,255 Cls ;Transparenz festlegen MaskImage testtile,255,0,255 MaskImage testchar,255,0,255 ;Aufruf der Spielersteuerung Spielersteuerung() ;Die Karte wird anhand der vorliegenden Mapinformationen gezeichnet For x = 0 To 19 For y = 0 To 14 DrawImage testtile,x*16,y*16,testmap(x,y) Next Next ;Charackter anzeigen DrawImage testchar,px,py,pDirGra ;Debuginformationen(Hinweis: Wird noch erweitert und als Console programmiert) Text 10,10,"Pos X: " + Str(px) + " Pos Y: " + Str(py) + " " Text 10,20,"TileX: " + Str(tileX) + " TileY: " + Str(tileY) + " " Text 10,30,"Tilenr.: " + Str(testmap(tileX,tileY)) + " " Text 10,50,"Result: " + Str(result) + " " ;Wenn die ESC-Taste gerdrückt wird, wird das Spiel beendet If KeyHit(ESC) Then leaveGame = 1 ;Den Backbuffer anzeigen lassen Flip ;Wenn das Spiel beendet wird werden noch alle Bilder aus dem Speicher gelöscht If leaveGame = 1 Then FreeImage testchar FreeImage testtile EndIf Wend ACHeader: Code: [AUSKLAPPEN] ;Konstanten Const links = 203 ;Konstanten Const rechts = 205 ;welche das Nutzen der Const oben = 200 ;Pfeiltasten etwas Const unten = 208 ;durchschaubarer machen Const ESC = 1 ;Konstante für die ESC-Taste ;Globale Variablen Global leaveGame = 0 ;Variable die das Beenden des Spiels prüft Global px# = 0 ;Bildschirmkoordinate des Spielers auf der X-Achse Global py# = 0 ;Bildschirmkoordinate des Spielers auf der Y-Achse Global pDirStatus = 0 ;Animationsframe Global pDirGra = 25 ;tatsächliche Grafik der Spielfigur Global steps = MilliSecs() ;Setzt die Schrittzahl auf die Milisekunden seit Systemstart Global tileX% = 0 ;Kachel auf dem der Spieler auf der X-Achse steht Global tileY% = 0 ;Kachel auf dem der Spieler auf der Y-Achse steht Global pSpeed = 1 ;Schnelligkeit des Spielers Global move = 0 ;Variable die abspeichert ob eine Bewegung geschehen ist oder nicht Global mSizeX = 19 ;Ausweitungsfaktor von X(in Pixel) auf der Karte Global mSizeY = 14 ;Ausweitungsfaktor von Y(in Pixel) auf der Karte Global result# = 0 ;Enthält das Ergebnis für die Kollisionsprüfung ;Definiert die Maße der Karte und speichert diese in einen Array Dim testmap(mSizeX,mSizeY) ;Datenfelder werden gesetzt um diese dann in die Mapdaten umzuwandeln Data 37,38,38,38,39,37,37,37,37,37,37,37,37,37,37,37,37,37,38,37 Data 38,38,38,37,37,37,37,37,37,37,37,37,37,38,37,37,37,38,38,38 Data 38,38,37,37,37,37,37,37,37,37,37,37,38,38,38,37,37,38,37,38 Data 38,38,37,37,37,37,37,37,37,37,37,37,38,38,37,37,37,37,37,38 Data 38,37,37,39,37,37,37,37,37,37,37,38,38,38,37,37,37,37,37,38 Data 37,37,37,37,37,37,37,37,37,37,37,38,38,37,37,37,37,37,37,37 Data 37,37,37,38,37,37,37,37,37,37,37,37,37,37,37,37,38,37,37,37 Data 39,37,37,37,37,39,37,37,38,38,37,37,37,37,37,37,38,38,37,37 Data 37,37,37,37,37,37,37,37,38,38,37,37,37,37,37,38,38,38,37,37 Data 37,37,37,37,37,37,37,38,38,38,38,37,37,37,37,38,38,38,37,37 Data 37,38,38,37,37,37,37,37,37,38,38,37,37,37,38,38,37,37,37,37 Data 38,38,38,37,37,37,37,37,37,38,38,38,37,37,38,38,37,37,37,37 Data 38,38,37,37,37,37,37,37,37,37,38,38,37,37,37,37,37,39,37,37 Data 38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37 Data 38,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,38 ;Liest die Datenfelder aus und speichert sie in den Maparray For y = 0 To 14 For x = 0 To 19 Read testmap(x,y) Next Next ;Hauptfunktion zum Steuern des Spielers.Diese Funktion ist grundlegend wichtig da ;sie Steuerung,Aktionsauslösung,TileKolisionen und eventuell noch andere ;Funktionen regelt Function Spielersteuerung() ;Tastenabfrage If KeyDown(links) And px > 0 Then ;Prüft ob durch die angesteuerte Bewegung der Spieler mit einem unbegebarem Tile kollidiert If TileKollision(links) = False Then ;Spielerbewegung px = px - pSpeed ;Fragt ab ob 100 Milisekunden nach dem letzten Bewegungszyklus vergangen sind und steuert ;somit die Bewegungsanimation, welche ansonsten unrealistisch schnel abläuft If steps + 100 < MilliSecs() Then ;Die momentan aktuelle Spielergrafiknummer wird zugewiesen damit die Richtige angezeigt wird If pDirStatus = 0 Then pDirGra = 37 If pDirStatus = 1 Then pDirGra = 38 If pDirStatus = 2 Then pDirGra = 36 ;Die Zeit wird aktualisiert steps = MilliSecs() pDirStatus = pDirStatus + 1 EndIf ;Fragt ab ob pDirStatus größer als 2 ist.Ist dies der Fall wird der Zähler wieder an den Anfang ;der Animation zurückgesetzt damit sie erneut ablaufen kann If pDirStatus > 2 Then pDirStatus = 0 ;Wenn der Spieler das nächstlegende Tile betritt wird die Tileposition aktualisiert If (px / 16) < (tileX) Then tileX = tileX - 1 EndIf ;Tastenabfrage ElseIf KeyDown(rechts) And px < 320 Then ;Prüft ob durch die angesteuerte Bewegung der Spieler mit einem unbegebarem Tile kollidiert If TileKollision(rechts) = False Then ;Spielerbewegung px = px + pSpeed ;Fragt ab ob 100 Milisekunden nach dem letzten Bewegungszyklus vergangen sind und steuert ;somit die Bewegungsanimation, welche ansonsten unrealistisch schnel abläuft If steps + 100 < MilliSecs() Then ;Die momentan aktuelle Spielergrafiknummer wird zugewiesen damit die Richtige angezeigt wird If pDirStatus = 0 Then pDirGra = 13 If pDirStatus = 1 Then pDirGra = 14 If pDirStatus = 2 Then pDirGra = 12 ;Die Zeit wird aktualisiert steps = MilliSecs() pDirStatus = pDirStatus + 1 EndIf ;Fragt ab ob pDirStatus größer als 2 ist.Ist dies der Fall wird der Zähler wieder an den Anfang ;der Animation zurückgesetzt damit sie erneut ablaufen kann If pDirStatus > 2 Then pDirStatus = 0 ;Wenn der Spieler das nächstlegende Tile betritt wird die Tileposition aktualisiert If (px / 16) > (tileX +1) Then tileX = tileX + 1 EndIf ElseIf KeyDown(oben) And py > 0 Then ;Prüft ob durch die angesteuerte Bewegung der Spieler mit einem unbegebarem Tile kollidiert If TileKollision(oben) = False Then ;Spielerbewegung py = py - pSpeed ;Fragt ab ob 100 Milisekunden nach dem letzten Bewegungszyklus vergangen sind und steuert ;somit die Bewegungsanimation, welche ansonsten unrealistisch schnel abläuft If steps + 100 < MilliSecs() Then ;Die momentan aktuelle Spielergrafiknummer wird zugewiesen damit die Richtige angezeigt wird If pDirStatus = 0 Then pDirGra = 1 If pDirStatus = 1 Then pDirGra = 2 If pDirStatus = 2 Then pDirGra = 0 ;Die Zeit wird aktualisiert steps = MilliSecs() pDirStatus = pDirStatus + 1 EndIf ;Fragt ab ob pDirStatus größer als 2 ist.Ist dies der Fall wird der Zähler wieder an den Anfang ;der Animation zurückgesetzt damit sie erneut ablaufen kann If pDirStatus > 2 Then pDirStatus = 0 ;Wenn der Spieler das nächstlegende Tile betritt wird die Tileposition aktualisiert If (py / 16) < (tileY) Then tileY = tileY - 1 EndIf ElseIf KeyDown(unten) And py < 240 Then ;Prüft ob durch die angesteuerte Bewegung der Spieler mit einem unbegebarem Tile kollidiert If TileKollision(unten) = False Then ;Spielerbewegung py = py + pSpeed ;Fragt ab ob 100 Milisekunden nach dem letzten Bewegungszyklus vergangen sind und steuert ;somit die Bewegungsanimation, welche ansonsten unrealistisch schnel abläuft If steps + 100 < MilliSecs() Then ;Die momentan aktuelle Spielergrafiknummer wird zugewiesen damit die Richtige angezeigt wird If pDirStatus = 0 Then pDirGra = 25 If pDirStatus = 1 Then pDirGra = 26 If pDirStatus = 2 Then pDirGra = 24 ;Die Zeit wird aktualisiert steps = MilliSecs() pDirStatus = pDirStatus + 1 EndIf ;Fragt ab ob pDirStatus größer als 2 ist.Ist dies der Fall wird der Zähler wieder an den Anfang ;der Animation zurückgesetzt damit sie erneut ablaufen kann If pDirStatus > 2 Then pDirStatus = 0 ;Wenn der Spieler das nächstlegende Tile betritt wird die Tileposition aktualisiert If (py / 16) > (tileY + 1) Then tileY = tileY + 1 EndIf Else ;Wenn kein Tastendruck registiert wurde,wird die Animation auf die Standanimation gesetzt pDirStatus = 0 EndIf Return pDirGra End Function ;Funktion welche entweder TRUE(1) oder FALSE(0) zurückliefert und somit prüft ob eine ;Kollision mit dem momentan angesteuerten Tile(curTile) stattfinden würde ;tileX udn TileY enthalten die Koordinaten des zu untersuchenden Tile Function TileKollision(pDir) ;Abfrage der Bewegungsrichtung(hier rechts) If pDir = rechts Then ;Die Tileposition für die angesteuerte Bewegung wird berechnet result = (px + 1) / 16 ;Sicherungsabfrage um zu verhindern das der Spieler außerhalb des Maparraybereiches gehen kann If tileX < mSizeX Then ;Abfrage welche prüft ob die berechnete Tileposition auf ein Tile passt welches nicht ;begehbar ist.st dies der Fall wird TRUE zurückgeliefert und die Bewegung verhindert If testmap(Floor(result),tileY) = 39 Then Return True EndIf EndIf ;Abfrage der Bewegungsrichtung(hier links) If pDir = links Then ;Die Tileposition für die angesteuerte Bewegung wird berechnet result = (px - 1) / 16 ;Sicherungsabfrage um zu verhindern das der Spieler außerhalb des Maparraybereiches gehen kann If tileX > 0 ;Abfrage welche prüft ob die berechnete Tileposition auf ein Tile passt welches nicht ;begehbar ist.st dies der Fall wird TRUE zurückgeliefert und die Bewegung verhindert If testmap(Floor(result),tileY) = 39 Then Return True EndIf EndIf ;Abfrage der Bewegungsrichtung(hier unten) If pDir = unten Then ;Die Tileposition für die angesteuerte Bewegung wird berechnet result = (py + 1) / 16 ;Sicherungsabfrage um zu verhindern das der Spieler außerhalb des Maparraybereiches gehen kann If tileY < mSizeY Then ;Abfrage welche prüft ob die berechnete Tileposition auf ein Tile passt welches nicht ;begehbar ist.st dies der Fall wird TRUE zurückgeliefert und die Bewegung verhindert If testmap(tileX,Floor(result)) = 39 Then Return True EndIf EndIf ;Abfrage der Bewegungsrichtung(hier unten) If pDir = oben Then ;Die Tileposition für die angesteuerte Bewegung wird berechnet result = (py - 1) / 16 ;Sicherungsabfrage um zu verhindern das der Spieler außerhalb des Maparraybereiches gehen kann If tileY > 0 Then ;Abfrage welche prüft ob die berechnete Tileposition auf ein Tile passt welches nicht ;begehbar ist.st dies der Fall wird TRUE zurückgeliefert und die Bewegung verhindert If testmap(tileX,Floor(result)) = 39 Then Return True EndIf EndIf End Function Bedanke mcih schonmal im Vorraus^^ MfG Ska [EDIT] Ich hab auch schon versucht per: Code: [AUSKLAPPEN] ;Charackter anzeigen DrawImage testchar,px-16,py-28,pDirGra eine Korrektur vorzunehme.Wenn cih den Chara dann nach Rechts bewege oder nach unten funktioniert das Ganze auch halbwegs.... Aber dann kann ich nicht exakt an einem nicht begehbarem Tile vorbeigehen oder die Bewegung von links wird nicht korrekt ausgeführt.Ich bin gerade etwas ratlos was ich da machen soll ![]() [/EDIT] [/code] |
||
"In einer so verrückten Welt, kann man um in ihr zu überleben nur eines tun, nämlich eben jenes werden: Ein Verrückter!" -Selbstzitat
aktuelles Projekt: Aves Certim - Der Galgen ist nicht weit! Ein SNES-RPG mit Handels- und Wirtschaftselemente. Infos?Hier: http://www.blitzforum.de/worklogs/234/ Besucht meine Seite: www.seelenfriedhof.de.vu |
![]() |
Skabus |
![]() Antworten mit Zitat ![]() |
---|---|---|
So....
Nachdem ich nun stundenlang rumprobiert habe, hab ich die Lösung gefunden: Code: [AUSKLAPPEN] Function TileKollision(pDir) ;Abfrage der Bewegungsrichtung(hier rechts) If pDir = rechts Then ;Die Karte wird nach alle Tiles durchsucht For y = 0 To mSizeY For x = 0 To mSizeX ;Wenn die Spielergrafik mit einem nicht begehbarem Tile kollidiert If (kollision = ImagesCollide(testtile,x*16,y*16,testmap(x,y),testchar,px-5,py,pDirGra)) = 0 Then ;Wird true zurückgegeben If testmap(x,y) = 39 Then Return True EndIf Next Next EndIf ;Abfrage der Bewegungsrichtung(hier links) If pDir = links Then For y = 0 To mSizeY For x = 0 To mSizeX If (kollision = ImagesCollide(testtile,x*16,y*16,testmap(x,y),testchar,px-5,py,pDirGra)) = 0 Then If testmap(x,y) = 39 Then Return True EndIf Next Next EndIf ;Abfrage der Bewegungsrichtung(hier unten) If pDir = unten Then For y = 0 To mSizeY For x = 0 To mSizeX If (kollision = ImagesCollide(testtile,x*16,y*16,testmap(x,y),testchar,px,py+5,pDirGra)) = 0 Then If testmap(x,y) = 39 Then Return True EndIf Next Next EndIf ;Abfrage der Bewegungsrichtung(hier unten) If pDir = oben Then For y = 0 To mSizeY For x = 0 To mSizeX If (kollision = ImagesCollide(testtile,x*16,y*16,testmap(x,y),testchar,px,py-5,pDirGra)) = 0 Then If testmap(x,y) = 39 Then Return True EndIf Next Next EndIf End Function Jetzt funktioniert das Ganze auch ordnungsgemäß und ohne Probleme. Nun habe ich aber ein neues Problem: Er erkennt nun folgerichtig wenn die Spielergrafik mit einem nicht begehbarem Tile kolidiert. Da ich aber ein Chara hab der nicht auf der Map liegt sondern draufsteht, sind nur die Füße des Charas auf der Karte aufliegend. Somit müsste also nur der Fußbereich des Charas geprüft werden, nicht die Spielergrafik selbst. Ich dachte ich mach das Ganze mittels eines "Dummys" den ich dann über den Fupbereich lege und frag dann nur noch die Kolision mit dem Fußbereich ab.Leider scheint das nicht zu funktionieren. Oder ich mache was falsch. Hat jemand ne Idee wie ich dieses Problem lösen könnte? MfG Ska |
||
"In einer so verrückten Welt, kann man um in ihr zu überleben nur eines tun, nämlich eben jenes werden: Ein Verrückter!" -Selbstzitat
aktuelles Projekt: Aves Certim - Der Galgen ist nicht weit! Ein SNES-RPG mit Handels- und Wirtschaftselemente. Infos?Hier: http://www.blitzforum.de/worklogs/234/ Besucht meine Seite: www.seelenfriedhof.de.vu |
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Mach Dir ein Bild auf dem nur die Fusssohlen 'eingezeichnet' sind, aber welches ansonsten dieselben Masse hat wie deine Playergraphik. Du musst da Bild nicht einzeichnen, es reicht wenn Du dieses Bild bei der Kollisionsprüfung als Quelle angibst. | ||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
![]() |
Skabus |
![]() Antworten mit Zitat ![]() |
---|---|---|
Dankeschön^^
Ich habs jetzt nochmal ausprobiert.Ich hab das ganze nun so geändert das es einen Positionsdummy gibt der als Quelle für die Kollision genommen wird.Die Spielergrafik wird dann nur genau an der Stelle des Positionsdummys angezeigt.So sieht der Spieler keinen Unterschied und die Kollision läuft richtig ab. Falls es aber jemanden gibt der ne Ahnung hat wie man das Ganze etwas eleganter lösen kann dann wäre ich sehr dankbar wenn er es hier posten könnte. Ich meine, es funktioniert perfekt aber ich glaub nicht dass das wirklich das ist was man "sauberes Programmieren" nennt XD MfG Ska |
||
"In einer so verrückten Welt, kann man um in ihr zu überleben nur eines tun, nämlich eben jenes werden: Ein Verrückter!" -Selbstzitat
aktuelles Projekt: Aves Certim - Der Galgen ist nicht weit! Ein SNES-RPG mit Handels- und Wirtschaftselemente. Infos?Hier: http://www.blitzforum.de/worklogs/234/ Besucht meine Seite: www.seelenfriedhof.de.vu |
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Es ist ein gebräuchlicher, ressourcenschonender und exakter Weg- was willst Du mehr ?
![]() |
||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
![]() |
Skabus |
![]() Antworten mit Zitat ![]() |
---|---|---|
BladeRunner hat Folgendes geschrieben: Es ist ein gebräuchlicher, ressourcenschonender und exakter Weg- was willst Du mehr ?
![]() Stimmt auch wieder XD Es mutet nur komisch an das man für jedes spielergleiches Objekt auf der Karte einen Positionsdummy braucht um die Kollision exakt zu bestimmen. Aber wenn das ein gebräuchlicher und exakter Weg ist bin ich ja vollends zufrieden^^ MfG Ska |
||
"In einer so verrückten Welt, kann man um in ihr zu überleben nur eines tun, nämlich eben jenes werden: Ein Verrückter!" -Selbstzitat
aktuelles Projekt: Aves Certim - Der Galgen ist nicht weit! Ein SNES-RPG mit Handels- und Wirtschaftselemente. Infos?Hier: http://www.blitzforum.de/worklogs/234/ Besucht meine Seite: www.seelenfriedhof.de.vu |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group