Pacman Kollisionsabfrage, mathematischer fehler?
Übersicht

DasLiebeSushiBetreff: Pacman Kollisionsabfrage, mathematischer fehler? |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Moin
Ich arbeite gerade an einem Pacman Klone. Level steht und die Kollision zum Teil auch. Das Problem scheint aber ein mathematisches zu sein. Ich hab ein Array/Dim(31,31) in dem meine Spielfigur rumläuft. Die Tiles sind 16x16 gross. Meine Spielfigur startet @ x256,y320 Die Kollision funktioniert aber nur teilweise und ungenau. Meine Spielfigur (auch 16x16 Pixel) lappt teilweise über die Wände hinaus oder läuft seitlich in eine Wand rein (Leider auch im Tutorial). Als Referenz für die Kollision habe ich das Jump´n Run Tutorial (tut2) von der "Robsite" genommen. Hier mal die Robsite Abfrage angepasst auf 16x16 Tiles (Kommentare sind aus dem Tutorial): Code: [AUSKLAPPEN] Function PacmanBewegen() ;Function um die Figur zu bewegen If KeyDown(links) Then ;Falls links gedrückt wird If map(Player_pos_x /16,(Player_pos_y +8) /16)=0 Then ;wenn Spielerposition / 16, weil die Tiles 16 * 16 groß sind ;PosY +8 um die Mitte zu bestimmen ;If Bedinung wird nur ausgeführt, wenn kein Tile neben der Figur ist. Player_pos_x = Player_pos_x -1 EndIf ElseIf KeyDown(rechts) Then If map((Player_pos_x +16) /16,(Player_pos_y +8) /16)=0 Then Player_pos_x = Player_pos_x +1 EndIf ElseIf KeyDown(rauf) Then If map((Player_pos_x +16) /16,Player_pos_y /16)=0 Then Player_pos_y = Player_pos_y -1 EndIf ElseIf KeyDown(runter) Then If map((Player_pos_x +16) /16,(Player_pos_y +8) /16)=0 Then Player_pos_y = Player_pos_y +1 EndIf EndIf End Function Die Abfrage des Randes hab ich erstmal entfernt. Wäre für jede Hilfe dankbar. MfG DasLiebeSushi |
||
- "Findet Nemo" wäre unendlich spannender gewesen, hätte Jack Bauer nach ihm gesucht.
- Falls du eine Pistole an Jack Bauers Kopf hälst, zähl bis 10 und nicht bis 3. So hast du 7 Sekunden länger zu leben. |
BlackTermi |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Mhh, auf die Gefahr hin mich lächerlich zu machen, weil ich den Fehler der evtl. drin ist nicht sehe, ich sehe da keinen Fehler. Es ist aber auch schwer nur anhand dieses Beispiels etwas dazu zu sagen. Was mich wundert ist allerdings das du sagst das deine startposition an x256,y320 ist und das du dieses dann mit einigen plus Werten (+8 und +16) durch 16 teilst. Denn das Ergebnis bestimmt ja das Array-Feld? (Krumme Zahlen!?)
Und dann zählst du zu der Player_pos_x immer nur einen dazu bzw. einen ab. Während du um die Position im Map-Array zu bestimmen ja durch 16 teilst - daraus schlußfolgere ich das ich also 16 mal drücken muss bis ich ein Feld weiterkomme? Um deinen Code nachvollziehen zu können wäre es hilfreich wenn du uns z.B. noch die Draw-Funktion dazu schreibst. |
||
DasLiebeSushi |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das sieht dann so aus:
Code: [AUSKLAPPEN] Global levelxpos = 144 ;Mittig zeichnen bbei 800x600 Global levelypos = 44 ;--------------------------------------------------------------------------------- ;Zeichnet den geladenen Level ;--------------------------------------------------------------------------------- Function ZeichneLevel() For Zeile=0 To 31 For Spalte=0 To 31 If Level(Spalte,Zeile) = 001 Then DrawImage levelstein,levelxpos+Spalte*16,levelypos+Zeile*16 ElseIf Level(Spalte,Zeile) = 002 Then DrawImage steinlo,levelxpos+Spalte*16,levelypos+Zeile*16 ElseIf Level(Spalte,Zeile) = 003 Then DrawImage steinro,levelxpos+Spalte*16,levelypos+Zeile*16 ElseIf Level(Spalte,Zeile) = 004 Then DrawImage steinlu,levelxpos+Spalte*16,levelypos+Zeile*16 ElseIf Level(Spalte,Zeile) = 005 Then DrawImage steinru,levelxpos+Spalte*16,levelypos+Zeile*16 ElseIf Level(Spalte,Zeile) = 006 Then DrawImage wandob,levelxpos+Spalte*16,levelypos+Zeile*16 ElseIf Level(Spalte,Zeile) = 007 Then DrawImage wandun,levelxpos+Spalte*16,levelypos+Zeile*16 ElseIf Level(Spalte,Zeile) = 008 Then DrawImage wandli,levelxpos+Spalte*16,levelypos+Zeile*16 ElseIf Level(Spalte,Zeile) = 009 Then DrawImage wandre,levelxpos+Spalte*16,levelypos+Zeile*16 ElseIf Level(Spalte,Zeile) = 010 Then DrawImage levelsupergold,levelxpos+Spalte*16,levelypos+Zeile*16,goldframe EndIf Next Next End Function ;--------------------------------------------------------------------------------- ;Lädt die Leveldaten aus einem Array ;--------------------------------------------------------------------------------- Function LadeLevel() Restore leveldaten For Zeile=0 To 31 For Spalte=0 To 31 Read Level(Spalte,Zeile) Next Next End Function ;################################################################################# ;Verschiedene Daten ;################################################################################# ;Level Daten ;--------------------------------------------------------------------------------- ;---------0|--1|--2|--3|--4|--5|--6|--7|--8|--9|-10|-11|-12|-13|-14|-15|-16|-17|-18|-19|-20|-21|-22|-23|-24|-25|-26|-27|-28|-29|-30|-31 ;-------------------------------------------------------------------------------------------------------------------------------------- .leveldaten Data 002,006,006,006,006,006,006,006,006,006,006,006,006,006,006,006,006,006,006,006,006,006,006,006,006,006,006,006,006,006,006,003 Data 008,010,000,000,000,000,000,000,000,000,000,000,000,000,000,001,001,000,000,000,000,000,000,000,000,000,000,000,000,000,010,009 Data 008,000,001,001,001,000,001,001,001,001,000,001,001,001,000,001,001,000,001,001,001,000,001,001,001,001,000,001,001,001,000,009 Data 008,000,001,001,001,000,001,001,001,001,000,001,001,001,000,001,001,000,001,001,001,000,001,001,001,001,000,001,001,001,000,009 Data 008,000,001,001,001,000,001,001,001,001,000,001,001,001,000,001,001,000,001,001,001,000,001,001,001,001,000,001,001,001,000,009 Data 008,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,009 Data 008,001,001,000,001,001,001,000,001,001,001,001,000,001,001,001,001,001,001,000,001,001,001,001,000,001,001,001,000,001,001,009 Data 008,001,001,000,001,001,001,000,001,001,001,001,000,001,001,001,001,001,001,000,001,001,001,001,000,001,001,001,000,001,001,009 Data 008,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,009 Data 008,000,001,001,001,000,001,001,001,001,000,001,001,001,001,001,001,001,001,001,001,000,001,001,001,001,000,001,001,001,000,009 Data 008,000,001,001,001,000,001,001,001,001,000,001,001,001,001,001,001,001,001,001,001,000,001,001,001,001,000,001,001,001,000,009 Data 008,000,001,001,001,000,001,001,001,001,000,000,000,000,000,000,000,000,000,000,000,000,001,001,001,001,000,001,001,001,000,009 Data 008,000,001,001,001,000,001,001,001,001,000,001,001,001,001,000,000,001,001,001,001,000,001,001,001,001,000,001,001,001,000,009 Data 008,000,001,001,001,000,001,001,001,001,000,001,000,000,000,000,000,000,000,000,001,000,001,001,001,001,000,001,001,001,000,009 Data 008,000,000,000,000,000,000,000,000,000,000,001,000,000,000,000,000,000,000,000,001,000,000,000,000,000,000,000,000,000,000,009 Data 008,001,000,001,001,001,001,001,001,001,000,001,000,000,000,000,000,000,000,000,001,000,001,001,001,001,001,001,001,000,001,009 Data 008,001,000,001,001,001,001,001,001,001,000,001,000,000,000,000,000,000,000,000,001,000,001,001,001,001,001,001,001,000,001,009 Data 008,000,000,000,000,000,000,000,000,000,000,001,000,000,000,000,000,000,000,000,001,000,000,000,000,000,000,000,000,000,000,009 Data 008,000,001,001,001,000,001,001,001,001,000,001,000,000,000,000,000,000,000,000,001,000,001,001,001,001,000,001,001,001,000,009 Data 008,000,001,001,001,000,001,001,001,001,000,001,001,001,001,001,001,001,001,001,001,000,001,001,001,001,000,001,001,001,000,009 Data 008,000,001,001,001,000,001,001,001,001,000,000,000,000,000,000,000,000,000,000,000,000,001,001,001,001,000,001,001,001,000,009 Data 008,000,001,001,001,000,001,001,001,001,000,001,001,001,001,001,001,001,001,001,001,000,001,001,001,001,000,001,001,001,000,009 Data 008,000,001,001,001,000,001,001,001,001,000,001,001,001,001,001,001,001,001,001,001,000,001,001,001,001,000,001,001,001,000,009 Data 008,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,009 Data 008,001,001,000,001,001,001,000,001,001,001,001,000,001,001,001,001,001,001,000,001,001,001,001,000,001,001,001,000,001,001,009 Data 008,001,001,000,001,001,001,000,001,001,001,001,000,001,001,001,001,001,001,000,001,001,001,001,000,001,001,001,000,001,001,009 Data 008,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,009 Data 008,000,001,001,001,000,001,001,001,001,000,001,001,001,000,001,001,000,001,001,001,000,001,001,001,001,000,001,001,001,000,009 Data 008,000,001,001,001,000,001,001,001,001,000,001,001,001,000,001,001,000,001,001,001,000,001,001,001,001,000,001,001,001,000,009 Data 008,000,001,001,001,000,001,001,001,001,000,001,001,001,000,001,001,000,001,001,001,000,001,001,001,001,000,001,001,001,000,009 Data 008,010,000,000,000,000,000,000,000,000,000,000,000,000,000,001,001,000,000,000,000,000,000,000,000,000,000,000,000,000,010,009 Data 004,007,007,007,007,007,007,007,007,007,007,007,007,007,007,007,007,007,007,007,007,007,007,007,007,007,007,007,007,007,007,005 Die Spielfigur setze ich mit DrawImage. MfG DasLiebeSushi |
||
- "Findet Nemo" wäre unendlich spannender gewesen, hätte Jack Bauer nach ihm gesucht.
- Falls du eine Pistole an Jack Bauers Kopf hälst, zähl bis 10 und nicht bis 3. So hast du 7 Sekunden länger zu leben. |
Krümel |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
um die Kollision korrekt zu ermitteln solltest du "floor" und "ceil" verwenden.
(schau dir mal den Code an) Ich wüde aber eher den pacman bei tastendruck mit einer schleife immer 16 pixel in die entsprechende Richtung laufen lassen. Damit vehinderst du das er an einer ecke "hängenbleibt" Code: [AUSKLAPPEN] Graphics 32*20,32*20,16,2 Global player_pos_x#=0,player_pos_y#=0 Global links=203,rechts=205,rauf=200,runter=208 Dim map(32,32) For y=0 To 31 For x=0 To 31 If Rand(0,10)=0 map(x,y)=1 Next Next Function PacmanBewegen() ;Function um die Figur zu bewegen mapXf=Floor((player_pos_x) / 16.0) mapYf=Floor((player_pos_y) / 16.0) mapXc=Ceil ((player_pos_x) / 16.0) mapYc=Ceil ((player_pos_y) / 16.0) Rect mapXf*16-8,mapYf*16-8,16,16,0 Rect mapXc*16-8,mapYc*16-8,16,16,0 ;wenn Spielerposition / 16, weil die Tiles 16 * 16 groß sind ;PosY +8 um die Mitte zu bestimmen ;If Bedinung wird nur ausgeführt, wenn kein Tile neben der Figur ist. If KeyDown(links) Then ;Falls links gedrückt wird If map(mapXf,mapYf)=0 And map(mapXf,mapYc)=0 Then Player_pos_x = Player_pos_x - 1 EndIf ElseIf KeyDown(rechts) Then If map(mapXf+1,mapYf)=0 And map(mapXf+1,mapYc)=0 Then Player_pos_x = Player_pos_x +1 EndIf ElseIf KeyDown(rauf) Then If map(mapXf,mapYf)=0 And map(mapXc,mapYf)=0 Then Player_pos_y = Player_pos_y -1 EndIf ElseIf KeyDown(runter) Then If map(mapXf,mapYf+1)=0 And map(mapXc,mapYf+1)=0 Then Player_pos_y = Player_pos_y +1 EndIf EndIf End Function While Not KeyHit(1) PacmanBewegen() Oval player_pos_x-8,player_pos_y-8,16,16´ For y=0 To 31 For x=0 To 31 If map(x,y)=1 Rect x*16-8,y*16-8,16,16 Next Next Delay 10 Flip 0 Cls Wend |
||
DasLiebeSushi |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Vielen Dank für deine Hilfe. Das mit den Recs als sichtbare Prüfung ist genial ![]() Hab es nun meiner Version angepasst. Leider berechnet er nur die Kollision nach unten und nach rechts genau. Bei der Kollision links und oben fehlt jeweils 1 Pixel. Mal schauen ob ich den Fehler finde. Trotzdem nochmal Danke ![]() MfG Sushi |
||
- "Findet Nemo" wäre unendlich spannender gewesen, hätte Jack Bauer nach ihm gesucht.
- Falls du eine Pistole an Jack Bauers Kopf hälst, zähl bis 10 und nicht bis 3. So hast du 7 Sekunden länger zu leben. |
Krümel |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
stimmt, da ist noch eine kleine ungenauigkeit...
so klappts: Code: [AUSKLAPPEN] Graphics 32*20,32*20,16,2 Global player_pos_x#=0,player_pos_y#=0 Global links=203,rechts=205,rauf=200,runter=208 Dim map(32,32) For y=0 To 31 For x=0 To 31 If Rand(0,10)=0 map(x,y)=1 Next Next Function PacmanBewegen() ;Function um die Figur zu bewegen mapXf=Floor((player_pos_x) / 16.0) mapYf=Floor((player_pos_y) / 16.0) mapXc=Ceil ((player_pos_x) / 16.0) mapYc=Ceil ((player_pos_y) / 16.0) Rect mapXf*16-8,mapYf*16-8,16,16,0 Rect mapXc*16-8,mapYc*16-8,16,16,0 ;wenn Spielerposition / 16, weil die Tiles 16 * 16 groß sind ;PosY +8 um die Mitte zu bestimmen ;If Bedinung wird nur ausgeführt, wenn kein Tile neben der Figur ist. If KeyDown(links) Then ;Falls links gedrückt wird mapXf=Floor((player_pos_x-1) / 16.0) mapXc=Ceil ((player_pos_x-1) / 16.0) If map(mapXf,mapYf)=0 And map(mapXf,mapYc)=0 Then Player_pos_x = Player_pos_x - 1 EndIf ElseIf KeyDown(rechts) Then If map(mapXf+1,mapYf)=0 And map(mapXf+1,mapYc)=0 Then Player_pos_x = Player_pos_x +1 EndIf ElseIf KeyDown(rauf) Then mapYf=Floor((player_pos_y-1) / 16.0) mapYc=Ceil ((player_pos_y-1) / 16.0) If map(mapXf,mapYf)=0 And map(mapXc,mapYf)=0 Then Player_pos_y = Player_pos_y -1 EndIf ElseIf KeyDown(runter) Then If map(mapXf,mapYf+1)=0 And map(mapXc,mapYf+1)=0 Then Player_pos_y = Player_pos_y +1 EndIf EndIf End Function While Not KeyHit(1) PacmanBewegen() Oval player_pos_x-8,player_pos_y-8,16,16´ For y=0 To 31 For x=0 To 31 If map(x,y)=1 Rect x*16-8,y*16-8,16,16 Next Next Delay 10 Flip 0 Cls Wend |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group