Pong Kollisions-Bug
Übersicht

![]() |
MoM007Betreff: Pong Kollisions-Bug |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi Leuts,
nach meinen ersten Schritten in BB habe ich vor kurzem begonnen ein Spiel zu programmieren, Pong. Es funktioniert auch wunderbar, die Schläger lassen sich bewegen, der Ball bewegt sich, es gibt einen Punktezähler und eine Reset-Funktion für den Ball. Das Problem ist jetzt die Kollision, nach 2-3 Berührungen des Balls mit den Schlägern oder der Wand bleibt der Ball einfach in der Wand oder den Schlägern stecken. Hat vielleicht jemad von Euch eine Idee, wie ich dieses Problem lösen kann? Danke! mom007 PS: wie kann ich den Ball denn schneller machen? Ich hab was probiert, ging aber nicht --CODE-- Code: AppTitle "Pong"
; --GLOBALS-- Global xmax=1024 Global ymax=768 Global yplayer2 = ymax / 2 Global yplayer1 = ymax / 2 Global move = 10 Global ball_speed Global xball# Global yball# Global winkel Global player1_points Global player2_points Graphics xmax,ymax,32,1 SeedRnd MilliSecs() ; --IMAGES-- player1=CreateImage(20,65) ;Player links SetBuffer ImageBuffer(player1) Color 255,255,255 Rect 0,0,20,65 MidHandle player1 player2=CreateImage(20,65) ;Player rechts SetBuffer ImageBuffer(player2) Color 255,255,255 Rect 0,0,20,65 MidHandle player2 ball=CreateImage(20,20) ;Ball SetBuffer ImageBuffer(ball) Color 255,255,255 Oval 0,0,20,20 MaskImage ball,0,0,0 MidHandle ball welt=CreateImage(xmax,ymax) ;Welt SetBuffer ImageBuffer(welt) Color 255,255,255 Rect 0,0,5,ymax ;Seitenwand links Rect xmax - 5,0,5,ymax ;Seitenwand rechts Line xmax / 2,ymax,xmax/2,0 ;Mittellinie .start FlushKeys() ; --NAMES UND SPEED-- SetBuffer FrontBuffer() Cls Locate xmax / 2 - xmax / 4,ymax / 2 player1_name$=Input("Spieler 1 ist links, bitte geben Sie ihren Namen ein: ") Cls Locate xmax / 2 - xmax / 4,ymax / 2 player2_name$=Input("Spieler 2 ist rechts, bitte geben Sie ihren Namen ein: ") Cls Locate xmax / 2 - xmax / 4,ymax / 2 ball_speed=Input("wählen Sie bitte eine Ballgeschwindidkeit von 1 bis 10: ") Cls Locate xmax / 2 - xmax / 4,ymax / 2 Print "um das Spiel zu starten, drücken Sie bitte 'ENTER'" WaitKey Cls If ball_speed > 10 Then ball_speed = 10 If ball_speed < 1 Then ball_speed = 1 SetBuffer BackBuffer() .reset resetball ; --HAUPTSCHLEIFE-- Repeat If KeyDown(200) Then yplayer2 = yplayer2 - move ;Bewegung Player rechts If KeyDown(208) Then yplayer2 = yplayer2 + move If KeyDown(16) Then yplayer1 = yplayer1 - move ;Bewegung Player links If KeyDown(30) Then yplayer1 = yplayer1 + move If yplayer1 < 10 Then yplayer1 = 10 ;Player Kontrolle, sie können nicht aus dem Feld verschwinden If yplayer2 < 10 Then yplayer2 = 10 If KeyDown(14) Then Goto start ;Spiel beginnt von Neuem If KeyDown(157) Then Goto reset ;Ball wird zurückgesetzt If ImagesCollide(player1,20,yplayer1,0,ball,xball,yball,0) Then ;Kollison vom Ball mit Spieler links winkel = 360 - winkel abweichung = 2 * (yplayer1 - yball) winkel = winkel - abweichung EndIf If ImagesCollide(player2,xmax - 20,yplayer2,0,ball,xball,yball,0) Then ;Kollison vom Ball mit Spieler rechts winkel = 360 - winkel abweichung = 2 * (yplayer2 - yball) winkel = winkel - abweichung EndIf If winkel > 360 Then winkel = 1;Winkelkontrolle If winkel < 0 Then winkel = 359 If yball < 5 Then ;Kollision mit Seitenwand oben winkel = 180 - winkel EndIf If yball > ymax - 5 Then ;Kollison mit Seitenwand unten winkel = 180 - winkel EndIf If xball < 5 Then ;Ball im Aus player1_points = player1_points + 1 ;Punkt für Player links resetball EndIf If xball > xmax Then ;Ball im Aus player2_points = player2_points + 1 ;Punkt für Player rechts resetball EndIf yball = yball + Cos(winkel) * ball_speed ;Ball Bewegung xball = xball - Sin(winkel) * ball_speed If yplayer1 < 10 Then yplayer1 = 10 ;Player Kontrolle, sie können nicht mehr aus dem Feld verschwinden If yplayer2 < 10 Then yplayer2 = 10 If yplayer1 > ymax - 10 Then yplayer1 = ymax - 10 ;die Spieler können nicht aus dem Bilderschirm verschwinden If yplayer2 > ymax - 10 Then yplayer2 = ymax - 10 DrawImage welt,0,0 ;Welt malen DrawImage ball,xball,yball ;Ball malen DrawImage player1,20,yplayer1 ;Player links malen DrawImage player2,xmax - 20,yplayer2 ;Player rechts malen Text 700,50,player1_name$ + ":" + player1_points ;Punkteanzeige Player links Text 100,50,player2_name$ + ":" + player2_points ;Punkteanzeige Player rechts Flip Cls Until KeyHit(1) End ; --FUNCTIONS-- Function resetball() xball = xmax / 2 yball = ymax / 2 If Rand(0,1) = 1 Then winkel = Rand(105,45) Else winkel = Rand(315,225) EndIf End Function Ball schneller Code: If ImagesCollide(player1,20,yplayer1,0,ball,xball,yball,0) Then ball_speed = ballspeed + 0.1 ElseIf ImagesCollide(player2,xmax - 20,yplayer2,0,ball,xball,yball,0) Then ball_speed = ballspeed + 0.1 ElseIf yball < 5 Then ball_speed = ballspeed + 0.1 ElseIf yball > ymax - 5 Then ball_speed = ballspeed + 0.1 EndIf |
||
AMD XP 2800+, 9600 256RAM, 1GB RAM, WIN XP PRO |
![]() |
FOODy |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich kann dir nicht sagen warum der ball stecken bleibt (hab nur BlitzMax), aber warum der Ball nicht schneller wird kann ich dir sagen.
Du musst ball_speed als Float Deklarieren. Also "Global ball_speed#". Im moment ist es eine Ganzahl (Integer), d.h. wenn du zu 1, 0.1 hinzuaddierst ist die Summe immernoch 1, weil bei einem Integer alles was nach dem "Komma" bzw "Punkt" "abgeschnitten" wird. Gruß, FOODy |
||
BlitzMax + MaxGUI, 64-bit Arch Linux: Intel Core² E8500 | 8 GB Ram | GeForce GTX 460 · 1024 MB |
![]() |
MoM007 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Stimmt, danke. Ich mach aber auch immer so kleine Noob-fehler... | ||
AMD XP 2800+, 9600 256RAM, 1GB RAM, WIN XP PRO |
![]() |
DerHase |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich nehme an, dass es daran liegt, dass sich Schläger und Ball überlappen. So wird die Richtung gewechselt, aber die Überlappung ist nicht aufgehoben. Also findet im nächsten Schleifendurchlauf erneut eine Kollision statt und die Richtung wechselt, aber die Überlappung bleibt immer noch.
Es gibt zwei Sachen die dies lösen können. Eine ist sich die alte Position des Balles zu merken und den Ball nach der Richtungsänderung dort hinzuversetzen. Dies ist bisschen unschön, da so eine kleine Lücke zwischen Ball und schläger entsteht. Ausserdem könnte der Ball wieder komische Sachen machen, wenn der Schläger sich bewegt und mit seiner Seite den Ball trifft. Die andere Möglichkeit ist es den Ball bei der Kollision an den Rand des Schläger zu versetzen. Bei einem Rechteck ist das gar nicht so schwer, da man ja seine Größe und Position kennt. Bei unförmigen Sachen muss man wie oben die alte Position speichern und das Objekt solange darauf zu bewegen, bis keine Kollision mehr statt findet. |
||
Play Satyr! |
![]() |
TheMatrix |
![]() Antworten mit Zitat ![]() |
---|---|---|
So, ich hab mal versucht, dein Problem zu lösen. Ersetze einfach diese Teile:
Zitat: ... If ball_speed < 1 Then ball_speed = 1 ball_speed_x = ball_speed ; <-- Eigener Speed Wert für X und ball_speed_y = ball_speed ; <-- Y ... Zitat: ... If yball < 5 Then ;Kollision mit Seitenwand oben ball_speed_y = ball_speed_y*-1 : yball=6 ; <-- Rücksetzen des Y-Wertes, Vorzeichen werden vertauscht EndIf If yball > ymax - 5 Then ;Kollison mit Seitenwand unten ball_speed_y = ball_speed_y*-1 : yball = ymax - 6 EndIf ... Zitat: ... yball = yball + Cos(winkel) * ball_speed_y ;Ball Bewegung <-- Die 2. Die Bewegung findet nun separat über ein X und Y Speed statt xball = xball - Sin(winkel) * ball_speed_x If yplayer1 < 10 Then yplayer1 = 10 ;Player Kontrolle, sie können nicht mehr aus dem Feld verschwinden ... Das mit dem Ball feststecken hat der Hase gut erklärt. Ich habe dir dieses Porblem mal mit einer anderen Variante gelöst. Es gibt jetzt für X und Y des Balls einen eigenen Speed Wert, der bei Aufprall auf die Wand einfach mal -1 genommen wird. Dadurch wird nur Y beim Speed so umgekehrt, das ein Abprall Effekt entsteht. Ich glaube es ist nicht so gut den Winkel = 180 - Winkel bei X und Y setzten. Das seperat für jede Variabel beim Auprall passieren. |
||
°_° °.° °~° °v° .. -.- |
![]() |
MoM007 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wenn ich es so mach, wie TheMatrix sagt, geth es immer noch nicht!
Der Code sieht dann bei mir so aus. (Also der Ball bleibt immer oben oder unten stecken und an den Schlägern prallt er manchmal richtig ab, manchmal nicht...) Code: AppTitle "Pong" ; --GLOBALS-- Global xmax=1024 Global ymax=768 Global yplayer2 = ymax / 2 Global yplayer1 = ymax / 2 Global move = 10 Global ball_speed# Global xball# Global yball# Global winkel Global player1_points Global player2_points Graphics xmax,ymax,32,1 SeedRnd MilliSecs() ; --IMAGES-- player1=CreateImage(20,65) ;Player links SetBuffer ImageBuffer(player1) Color 255,255,255 Rect 0,0,20,65 MidHandle player1 player2=CreateImage(20,65) ;Player rechts SetBuffer ImageBuffer(player2) Color 255,255,255 Rect 0,0,20,65 MidHandle player2 ball=CreateImage(20,20) ;Ball SetBuffer ImageBuffer(ball) Color 255,255,255 Oval 0,0,20,20 MaskImage ball,0,0,0 MidHandle ball welt=CreateImage(xmax,ymax) ;Welt SetBuffer ImageBuffer(welt) Color 255,255,255 Rect 0,0,5,ymax ;Seitenwand links Rect xmax - 5,0,5,ymax ;Seitenwand rechts Line xmax / 2,ymax,xmax/2,0 ;Mittellinie .start FlushKeys() ; --NAMES UND SPEED-- SetBuffer FrontBuffer() Cls Locate xmax / 2 - xmax / 4,ymax / 2 player1_name$=Input("Spieler 1 ist links, bitte geben Sie ihren Namen ein: ") Cls Locate xmax / 2 - xmax / 4,ymax / 2 player2_name$=Input("Spieler 2 ist rechts, bitte geben Sie ihren Namen ein: ") Cls Locate xmax / 2 - xmax / 4,ymax / 2 ball_speed=Input("wählen Sie bitte eine Ballgeschwindidkeit von 1 bis 10: ") Cls Locate xmax / 2 - xmax / 4,ymax / 2 Print "um das Spiel zu starten, drücken Sie bitte 'ENTER'" WaitKey Cls If ball_speed > 10 Then ball_speed = 10 If ball_speed < 1 Then ball_speed = 1 SetBuffer BackBuffer() .reset resetball ; --HAUPTSCHLEIFE-- Repeat If KeyDown(200) Then yplayer2 = yplayer2 - move ;Bewegung Player rechts If KeyDown(208) Then yplayer2 = yplayer2 + move If KeyDown(16) Then yplayer1 = yplayer1 - move ;Bewegung Player links If KeyDown(30) Then yplayer1 = yplayer1 + move If yplayer1 < 10 Then yplayer1 = 10 ;Player Kontrolle, sie können nicht aus dem Feld verschwinden If yplayer2 < 10 Then yplayer2 = 10 If KeyDown(14) Then Goto start ;Spiel beginnt von Neuem If KeyDown(157) Then Goto reset ;Ball wird zurückgesetzt If ImagesCollide(player1,20,yplayer1,0,ball,xball,yball,0) Then ;Kollison vom Ball mit Spieler links winkel = 360 - winkel abweichung = 2 * (yplayer1 - yball) winkel = winkel - abweichung EndIf If ImagesCollide(player2,xmax - 20,yplayer2,0,ball,xball,yball,0) Then ;Kollison vom Ball mit Spieler rechts winkel = 360 - winkel abweichung = 2 * (yplayer2 - yball) winkel = winkel - abweichung EndIf If winkel > 360 Then winkel = 1;Winkelkontrolle If winkel < 0 Then winkel = 359 If ball_speed < 1 Then ball_speed = 1 ball_speed_x = ball_speed ;Eigener Speed Wert für X und ball_speed_y = ball_speed ;Y If yball < 5 Then ;Kollision mit Seitenwand oben ball_speed_y = ball_speed_y*-1 : yball=6 ;Rücksetzen des Y-Wertes, Vorzeichen werden vertauscht EndIf If yball > ymax - 5 Then ;Kollison mit Seitenwand unten ball_speed_y = ball_speed_y*-1 : yball = ymax - 6 EndIf If xball < 5 Then ;Ball im Aus player1_points = player1_points + 1 ;Punkt für Player links resetball EndIf If xball > xmax Then ;Ball im Aus player2_points = player2_points + 1 ;Punkt für Player rechts resetball EndIf yball = yball + Cos(winkel) * ball_speed_y ;Ball Bewegung <-- Die 2. Die Bewegung findet nun separat über ein X und Y Speed statt xball = xball - Sin(winkel) * ball_speed_x If yplayer1 < 10 Then yplayer1 = 10 ;Player Kontrolle, sie können nicht mehr aus dem Feld verschwinden If yplayer2 < 10 Then yplayer2 = 10 If yplayer1 > ymax - 10 Then yplayer1 = ymax - 10 ;die Spieler können nicht aus dem Bilderschirm verschwinden If yplayer2 > ymax - 10 Then yplayer2 = ymax - 10 If ImagesCollide(player1,20,yplayer1,0,ball,xball,yball,0) Then ;wenn Kollision oben, unten, Spieler rechts ball_speed = ballspeed + 0.1 ;oder links wir der Ballspeed erhöt ElseIf ImagesCollide(player2,xmax - 20,yplayer2,0,ball,xball,yball,0) Then ball_speed = ballspeed + 0.1 ElseIf yball < 5 Then ball_speed = ballspeed + 0.1 ElseIf yball > ymax - 5 Then ball_speed = ballspeed + 0.1 EndIf DrawImage welt,0,0 ;Welt malen DrawImage ball,xball,yball ;Ball malen DrawImage player1,20,yplayer1 ;Player links malen DrawImage player2,xmax - 20,yplayer2 ;Player rechts malen Text 700,50,player1_name$ + ":" + player1_points ;Punkteanzeige Player links Text 100,50,player2_name$ + ":" + player2_points ;Punkteanzeige Player rechts Flip Cls Until KeyHit(1) End ; --FUNCTIONS-- Function resetball() xball = xmax / 2 yball = ymax / 2 If Rand(0,1) = 1 Then winkel = Rand(105,45) Else winkel = Rand(315,225) EndIf End Function Es kann aber auch genau so gut sein, dass irgendeinen Fehler gemacht habe... aber danke für deine Hilfe Die Lösung vom Hasen ist auch gut, nur hab ich im Moment keinen Nerv das zu proggen, ich machs aber Morgen, dake für die guten Ideen |
||
AMD XP 2800+, 9600 256RAM, 1GB RAM, WIN XP PRO |
![]() |
TheMatrix |
![]() Antworten mit Zitat ![]() |
---|---|---|
Bitte schließt den Code hier nich, wenn ichs nochma poste, aber es hilft halt nich ![]() Der Code: AppTitle "Pong" ; --GLOBALS-- Global xmax=1024 Global ymax=768 Global yplayer2 = ymax / 2 Global yplayer1 = ymax / 2 Global move = 10 Global ball_speed# Global xball# Global yball# Global winkel Global player1_points Global player2_points Graphics xmax,ymax,32 SeedRnd MilliSecs() ; --IMAGES-- player1=CreateImage(20,65) ;Player links SetBuffer ImageBuffer(player1) Color 255,255,255 Rect 0,0,20,65 MidHandle player1 player2=CreateImage(20,65) ;Player rechts SetBuffer ImageBuffer(player2) Color 255,255,255 Rect 0,0,20,65 MidHandle player2 ball=CreateImage(20,20) ;Ball SetBuffer ImageBuffer(ball) Color 255,255,255 Oval 0,0,20,20 MaskImage ball,0,0,0 MidHandle ball welt=CreateImage(xmax,ymax) ;Welt SetBuffer ImageBuffer(welt) Color 255,255,255 Rect 0,0,5,ymax ;Seitenwand links Rect xmax - 5,0,5,ymax ;Seitenwand rechts Line xmax / 2,ymax,xmax/2,0 ;Mittellinie .start FlushKeys() ; --NAMES UND SPEED-- SetBuffer FrontBuffer() Cls Locate xmax / 2 - xmax / 4,ymax / 2 player1_name$=Input("Spieler 1 ist links, bitte geben Sie ihren Namen ein: ") Cls Locate xmax / 2 - xmax / 4,ymax / 2 player2_name$=Input("Spieler 2 ist rechts, bitte geben Sie ihren Namen ein: ") Cls Locate xmax / 2 - xmax / 4,ymax / 2 ball_speed=Input("wählen Sie bitte eine Ballgeschwindidkeit von 1 bis 10: ") Cls Locate xmax / 2 - xmax / 4,ymax / 2 Print "um das Spiel zu starten, drücken Sie bitte 'ENTER'" WaitKey Cls If ball_speed > 10 Then ball_speed = 10 If ball_speed < 1 Then ball_speed = 1 ; --------- Hier -------------- <-- Hier meinte ich, solltest du das einsetzen ball_speed_x = ball_speed ;Eigener Speed Wert für X und ball_speed_y = ball_speed ;Y ; --------- Ende -------------- SetBuffer BackBuffer() .reset resetball ; --HAUPTSCHLEIFE-- Repeat If KeyDown(200) Then yplayer2 = yplayer2 - move ;Bewegung Player rechts If KeyDown(208) Then yplayer2 = yplayer2 + move If KeyDown(16) Then yplayer1 = yplayer1 - move ;Bewegung Player links If KeyDown(30) Then yplayer1 = yplayer1 + move If yplayer1 < 10 Then yplayer1 = 10 ;Player Kontrolle, sie können nicht aus dem Feld verschwinden If yplayer2 < 10 Then yplayer2 = 10 If KeyDown(14) Then Goto start ;Spiel beginnt von Neuem If KeyDown(157) Then Goto reset ;Ball wird zurückgesetzt If ImagesCollide(player1,20,yplayer1,0,ball,xball,yball,0) Then ;Kollison vom Ball mit Spieler links winkel = 360 - winkel abweichung = 2 * (yplayer1 - yball) winkel = winkel - abweichung EndIf If ImagesCollide(player2,xmax - 20,yplayer2,0,ball,xball,yball,0) Then ;Kollison vom Ball mit Spieler rechts winkel = 360 - winkel abweichung = 2 * (yplayer2 - yball) winkel = winkel - abweichung EndIf If winkel > 360 Then winkel = 1;Winkelkontrolle If winkel < 0 Then winkel = 359 If ball_speed < 1 Then ball_speed = 1 If yball < 5 Then ;Kollision mit Seitenwand oben ball_speed_y = ball_speed_y*-1 : yball=6 ;Rücksetzen des Y-Wertes, Vorzeichen werden vertauscht EndIf If yball > ymax - 5 Then ;Kollison mit Seitenwand unten ball_speed_y = ball_speed_y*-1 : yball = ymax - 6 EndIf If xball < 5 Then ;Ball im Aus player1_points = player1_points + 1 ;Punkt für Player links resetball EndIf If xball > xmax Then ;Ball im Aus player2_points = player2_points + 1 ;Punkt für Player rechts resetball EndIf yball = yball + Cos(winkel) * ball_speed_y ;Ball Bewegung <-- Die 2. Die Bewegung findet nun separat über ein X und Y Speed statt xball = xball - Sin(winkel) * ball_speed_x If yplayer1 < 10 Then yplayer1 = 10 ;Player Kontrolle, sie können nicht mehr aus dem Feld verschwinden If yplayer2 < 10 Then yplayer2 = 10 If yplayer1 > ymax - 10 Then yplayer1 = ymax - 10 ;die Spieler können nicht aus dem Bilderschirm verschwinden If yplayer2 > ymax - 10 Then yplayer2 = ymax - 10 If ImagesCollide(player1,20,yplayer1,0,ball,xball,yball,0) Then ;wenn Kollision oben, unten, Spieler rechts ball_speed = ballspeed + 0.1 ;oder links wir der Ballspeed erhöt ElseIf ImagesCollide(player2,xmax - 20,yplayer2,0,ball,xball,yball,0) Then ball_speed = ballspeed + 0.1 ElseIf yball < 5 Then ball_speed = ballspeed + 0.1 ElseIf yball > ymax - 5 Then ball_speed = ballspeed + 0.1 EndIf DrawImage welt,0,0 ;Welt malen DrawImage ball,xball,yball ;Ball malen DrawImage player1,20,yplayer1 ;Player links malen DrawImage player2,xmax - 20,yplayer2 ;Player rechts malen Text 700,50,player1_name$ + ":" + player1_points ;Punkteanzeige Player links Text 100,50,player2_name$ + ":" + player2_points ;Punkteanzeige Player rechts Flip Cls Until KeyHit(1) End ; --FUNCTIONS-- Function resetball() xball = xmax / 2 yball = ymax / 2 If Rand(0,1) = 1 Then winkel = Rand(105,45) Else winkel = Rand(315,225) EndIf End Function So, du musst den Variabeln ball_speed_x und ball_speed_y am Anfang die zuweisung durch ball_speed geben. Sonst gehts ja auch nich. |
||
°_° °.° °~° °v° .. -.- |
![]() |
MoM007 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Danke, von alleine wäre ich wohl nicht drauf gekommen... | ||
AMD XP 2800+, 9600 256RAM, 1GB RAM, WIN XP PRO |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group