Pong Problem

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

 

Mori

Betreff: Pong Problem

BeitragSo, Jan 29, 2012 22:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Blitz Basic Forum,

ich bin ein Einsteiger und gerade dabei ein Pong zu schreiben. Eigentlich dachte ich es sei nicht weiter schwierig zumindest weiß ich was Cosinus und Sinus können. Aber irgendwie habe ich einen Denkfehler und weiß nicht genau was ich falsch mache, da ich mir auch nicht genau Visualisieren kann, was mein Problem ist. Ich habe mir auch dieses Video angeguckt http://www.youtube.com/watch?v=qdpxanCY04M, aber das hat leider auch nicht den Nebel in meinem Kopf gelichtet.

BlitzBasic: [AUSKLAPPEN]
timer = CreateTimer (60)
SeedRnd MilliSecs()
Graphics 640,480,32,2
SetBuffer BackBuffer()

Global winkel# = 90
Global speed# = 1
Global px1# = GraphicsWidth()/2-40
Global py1# = 460
Global px2# = GraphicsWidth()/2-40
Global py2# = 20

Global ball_x# = GraphicsWidth()/2-10
Global ball_y# = GraphicsHeight()/2-10
While Not KeyHit (1) ; ESC
;Text 50,50,"Debug"
Cls

;Schläger Steuerung
If KeyDown(205) Then px1=px1 + 2.5
If KeyDown(203) Then px1=px1 - 2.5

;Schläger Wand Kollision
If px1 <= 1 Then px1 = 1
If px1 >= 560 Then px1 = 560

;Schläger
Rect px1,py1,80,1
Rect px2,py2,80,1

;Ball Steuerung
ball_x = ball_x + Cos(winkel)*speed
ball_y = ball_y + Sin(winkel)*speed

;Kollisionsüberpruefung
If RectsOverlap(px1,py1,80,1,ball_x,ball_y,20,20) Then
Text 50,50,"KOLLISION!"
End If

If RectsOverlap(px1,py1,80,1,ball_x,ball_y,20,20) Then
winkel=Rand(0,135)-winkel ;Winkel neu berechnen
EndIf

If RectsOverlap(px2,py2,80,1,ball_x,ball_y,20,20) Then
winkel=Rand(225,360)-winkel ;Winkel neu berechnen
EndIf

If ball_x < 1 Then winkel=Rand(1,180)
If ball_x > 620 Then winkel=Rand(181,360)
If ball_y < 1 Then winkel=Rand(1,180)
If ball_y > 460 Then winkel=Rand(181,360)

If winkel>360 Then winkel=winkel-360
If winkel<0 Then winkel=winkel+360



Text 80,100, px1+ " " +py1
Text 80,120, ball_x+ " " +ball_y
Text 80,140, winkel

;Ball
Rect ball_x,ball_y,20,20

WaitTimer timer
Flip 0
Wend
End


P.S.: Ich hatte als erstes für den Ball anstatt Rect, Oval drinne, deswegen heißen die Variablen noch ball_x/ball_y


LG Mori

Xeres

Moderator

BeitragSo, Jan 29, 2012 22:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Und wo liegt nun dein Problem?
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

ZaP

BeitragSo, Jan 29, 2012 22:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Naja, wenn Du dein Problem nicht beschreiben kannst, müssen wir halt raten, versuchs doch nochmal! Das einzige was ich als problematisch ansehe, ist, dass der Ball in eine Zufallsrichtung fliegt, wenn er von irgendwas abprallt.

Btw, dein Code-Stil ist ganz Exzellent für einen Einsteiger, damit wirst Du einmal zu einem mächtigen Jedi werden Very Happy
Starfare: Worklog, Website (download)
 

Mori

BeitragSo, Jan 29, 2012 22:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Also das genaue Problem ist, dass der "Ball" nach öfterem starten des Spiels, einfach manchmal im Schläger hängen bleibt, darin rum "zappelt" und dann weiter fliegt genauso ist es mit der Kollision, an der Wand. Ich schätze mal das es ein Berechnungsfehler ist, dass meinte ich auch mit Visualisieren, sorry muss mich da wohl das nächste mal etwas besser ausdrücken: Ich verstehe nicht warum der Ball so handelt wie er es tut und nicht so wie ich es bei einem normalen Pong erwarten würde, vor allem im Bezug auf dieses "Zappeln".

LG Mori
  • Zuletzt bearbeitet von Mori am So, Jan 29, 2012 23:15, insgesamt einmal bearbeitet

Xeres

Moderator

BeitragSo, Jan 29, 2012 22:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Problem mit RectsOverlap ist, dass es so lange True zurück gibt, wie Schläger und Ball überlappen. Oder anders ausgedrückt: Der Ball bewegt sich so langsam, dass er bei der nächsten Prüfung immer noch in dem Bereich ist, der eine Änderung bewirkt. Ich würde die Kollision für eine gewisse Zeit abstellen, bis der Ball mit Sicherheit wieder auf dem Feld gelandet ist.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

Mori

BeitragMo, Jan 30, 2012 13:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

ich habe probiert zu machen was Xeres gesagt hat:
BlitzBasic: [AUSKLAPPEN]

If Kollision = True
If RectsOverlap(px1,py1,80,1,ball_x,ball_y,20,20)
Text 50,50,"KOLLISION!"
Kollision = False
winkel=180-winkel ;Winkel neu berechnen
EndIf
EndIf


If ball_x < 1 Then winkel=Rand(45,135): Kollision = True ; NUR WENN eine der Seitenwände berührt wurde ist Kollision wieder möglich
If ball_x > 620 Then winkel=Rand(135,225): Kollision = True
If ball_y < 1 Then winkel=Rand(100,180)
If ball_y > 460 Then winkel=Rand(181,360)


Mein Ansatz: sobald die Kugel eine Kollision mit dem Schläger hat wird die Kollision = False und wird erst dann wieder True, wenn du Kugel eine von den Seitenwänden berührt hat, soweit zur Theorie. In der Praxis aber bleibt das Problem bestehen, was mache ich falsch?

LG Mori

Midimaster

BeitragMo, Jan 30, 2012 13:47
Antworten mit Zitat
Benutzer-Profile anzeigen
mein tipp: führe bei einer Kollision gleich noch eine erste Bewegung in die neue Richtung aus! Also warte nicht, bis die reguläre Bewegungsaddition erfolgt. Dann ist dein Ball beim nächsten Mal schon garantiert weg vom Schläger! Bei dieser Berechnung könntest Du auch den y-Wert des Ball aus SchlägerY-10 faken!

So ein Fehler tritt immer dann auf, wenn der Ball unmittelbar vor der Kollision schon supernahm am Schläger war und durch die nächste Bewegungsaddition eigentlich schon weit hinter (unter) dem Schläger zu liegen kommt. Da du bei der Kollision mit dem Schläger per Zufall einen neuen Winkel auswähslt, kann es nun sein, dass der x-Anteil der Bewegung nicht ausreicht um bei der nächsten Bewegung den Ball wirklich aus dem Kollisionsbereich zu befördern. D.h. manchmal reicht die nächste Addition nicht aus, um ihn aus dem Kollisionsbereich herauszubringen. Folge: erneute Kollision und Richtungsumkehr. Nun liegt er wieder zu weit hinter dem Schläger...u.w.s. Daher das Zittern.
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe
  • Zuletzt bearbeitet von Midimaster am Mo, Jan 30, 2012 13:52, insgesamt einmal bearbeitet

Xeres

Moderator

BeitragMo, Jan 30, 2012 13:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Das ist schon mal keine gute Lösung, weil du dir nicht sicher sein kannst, dass der Ball eine Seite berührt.
Mit Millisecs ginge es etwa so:
BlitzBasic: [AUSKLAPPEN]
;Kollisionsüberpruefung
If KollisionTime = 0 Then
If RectsOverlap(px1,py1,80,1,ball_x,ball_y,20,20)
Text 50,50,"Unten"
KollisionTime = MilliSecs()+250 ;* 1/4 Sekunde in der Zukunft
winkel=270 ;Winkel neu berechnen
EndIf

If RectsOverlap(px2,py2,80,1,ball_x,ball_y,20,20)
Text 50,50,"Oben"
KollisionTime = MilliSecs()+250 ;* 1/4 Sekunde in der Zukunft
winkel=90 ;winkel neu berechnen
EndIf
ElseIf KollisionTime<MilliSecs() Then ;** Die Aktuelle Zeit hat die gespeicherte überholt
KollisionTime=0
EndIf


Edit:
Vielleicht noch simpler: du bewegst den Ball so lange in die neuen Richtung, bis er nicht mehr Kollidiert:
BlitzBasic: [AUSKLAPPEN]
;Kollisionsüberpruefung

If RectsOverlap(px1,py1,80,1,ball_x,ball_y,20,20)
Text 50,50,"Unten"
winkel=270 ;Winkel neu berechnen

While RectsOverlap(px1,py1,80,1,ball_x,ball_y,20,20)
;* Solange Kollision:
ball_x = ball_x + Cos(winkel)*speed
ball_y = ball_y + Sin(winkel)*speed
Wend
EndIf

If RectsOverlap(px2,py2,80,1,ball_x,ball_y,20,20)
Text 50,50,"Oben"
winkel=90 ;winkel neu berechnen

While RectsOverlap(px2,py2,80,1,ball_x,ball_y,20,20)
;* Solange Kollision:
ball_x = ball_x + Cos(winkel)*speed
ball_y = ball_y + Sin(winkel)*speed
Wend
EndIf
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

Mori

BeitragMo, Jan 30, 2012 14:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

Danke erstmal für die Lösungsvorschläge, habe es jetzt geschafft. Komischerweise war die Lösung des Problems einfach
BlitzBasic: [AUSKLAPPEN]
winkel=180-winkel ;Winkel neu berechnen

in
BlitzBasic: [AUSKLAPPEN]
winkel=360-winkel ;Winkel neu berechnen

zu ändern danach klappte plötzlich alles.

LG Mori
 

PhillipK

BeitragMo, Jan 30, 2012 17:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Tu dir aber selbst einen gefallen und bau eine "mit dem grade kollidierten schläger nicht noch einmal kollidieren" verzögerung ein.

Xeres vorschlag ist Millisekunden basiert, meiner wäre distanz basiert (wenn mindestens eine ballgröße unterschied zwischen ball und grade kollidiertem schläger ist, kollision mit schläger wieder erlauben)

Midimasters vorschlag ist auch akzeptabel - erstmal vom schläger wegbewegen.

Naja grundlegend: Wenn es in 1000 versuchen klappt, kann es im 1001sten versuch immernoch eine änderung zu den vorherigen versuchen haben, wodurch du wieder deinen Bug erhälst.
Oder wenn du vielleicht die features ausbaust - dh einsammelbare powerups, welche weitere bälle erzeugen (und diese auch in der luft kollidieren können) Smile

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group