Pong - Pad Kollision
Übersicht

Till P.Betreff: Pong - Pad Kollision |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Halli Hallo, ich bin wieder da!
Und ich hab auch gleich eine Frage mitgebracht: ![]() Ich arbeite gerade an einem (etwas anderen...) Pong Klon. Das klappt auch alles ganz wunderbar, doch ich habe folgendes Problem: Ich prüfe den Ball folgendermaßen auf eine Kollision mit dem Pad Wenn Ball auf der Höhe des Pads AND Ball_x <= Pad_x, dann Abprallen So, ein Tor gibt's... Wenn Ball_x < 0 Wenn die Geschwindigkeit des Balles zunimmt, dann legt er bis zu 60 Pixel pro Schleifendurchlauf zurück. Dadurch ist es Möglich, dass er das Pad quasi überspringt und hindurchfliegt. (er ist also in Schleifendurchlauf 335 10 Pixel vor dem Pad und im 336. Durchlauf schon 50 Pixel dahinter...) Ich hab mir dann gedacht, ich erhöhe einfach die Pufferzone der Kollision. Das heißt Tor gibt's.... Wenn Ball_x < -60 Jo, hat also funktionier und ich war ganz happy, ABER!!! Wenn der Ball von oben nach unten fliegt und quasi schräg über dem Pad ins aus geht, so ist er hinter dem Pad auf höhe des Pads (bevor ein Tor gezählt wird --> erst ab x=-50) und prallt ab. Wie kann ich diese Problem lösen? Und noch etwas... Ich möchte das Spiel um die Möglichkeit erweitern, das Pad auf der X Achse zu bewegen... gibt es eine Möglichkeit das zu machen, ohne die oben genannten Fehler zu bekommen? So, Vielen Dank schon mal für's lesen (ist ja nicht wenig) und noch mehr für Antworten! ![]() mfG Till |
||
![]() |
SpionAtom |
![]() Antworten mit Zitat ![]() |
---|---|---|
Diese Problem habe ich bei meinem Jump and Run -Spiel auch, welches ich gerade entwickle. Also man hat einen Punkt(A), wo man gerade ist, und einen Punkt(B), wo man hinmöchte.
Und zwar bin ich so vorgegangen. Ich habe einfach alle Punkte zwischen A und B auf Bodenkollision prüfe. So verhindere ich, dass die Figur beim runterfallen plötzlich "unter dem Boden" landet. Ich schicke hier mal keinen Quelltext rein, weil das bei mir selbst noch nicht richtig funktioniert. Aber ich hoffe der Ansatz hilft ![]() EDIT: Aber hier zumindest mal eine Möglichkeit, alle Punkte zwischen zwei Punkten auszurechnen. Code: [AUSKLAPPEN] Graphics 800, 600, 16, 2 SetBuffer BackBuffer() spx = 50: spy = 150 ;Startpunkt epx = 700: epy = 500 ;Endpunkt Repeat ;Eingaben If MouseDown(1) Then spx = MouseX():spy = MouseY() If MouseDown(2) Then epx = MouseX():epy = MouseY() Cls ;Hilfetext Color 0,150,0:Oval spx-10,spy-10,20,20,1 Color 0,0,150:Oval epx-10,epy-10,20,20,1 Color 255, 255, 255 Text spx-30, spy-25,"Startpunkt" Text epx-30, epy-25,"Endpunkt" Text 0,0,"Startpunkt setzen = Linksklick" Text 0,20, "Endpunkt setzen = Rechtsklick" ;Berechnung ;Es werden alle Punkte zwischen Startpunkt und Endpunkt angezeigt. abstand# = Sqr((spx-epx)^2 + (spy-epy)^2) xdif# = epx-spx ydif# = epy-spy Color 255,0,0 For i = 0 To abstand Plot spx + i*(xdif#/abstand), spy + i*(ydif#/abstand) Next Flip() Until KeyDown(1) |
||
os: Windows 10 Home cpu: Intel Core i7 6700K 4.00Ghz gpu: NVIDIA GeForce GTX 1080 |
![]() |
Goodjee |
![]() Antworten mit Zitat ![]() |
---|---|---|
warum bewegst du nicht den ball langsamer und checkst mir imagerectcollision() die kollision zwischen ball und padabschnitt | ||
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/ |
![]() |
KabelbinderSieger des WM-Contest 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wenn man den Ball zu langsam fliegen lässt, wird das Spiel aber zu langweilig.
Ich würde das so machen, wie SpionAtom das vogeschlagen hat. Dann prüfst eigentlich eine Linie zwischen dem Start und dem Ziel und wenn die durch das Brett geht, prallt er ab. |
||
<Wing Avenger Download> ◊◊◊ <Macrophage Download> |
Till P. |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
genau so hab ich's gemacht! Danke an alle!
Für andere, die vielleicht auch das Problem hatten, und aus diesem Thread noch nicht ganz schlau werden: Schreibt mir einfach eine email oder PM, ich weiß jetzt nämlich wie's geht! ![]() Danke nochmal! |
||
![]() |
Goodjee |
![]() Antworten mit Zitat ![]() |
---|---|---|
@kabelbinder:
man sollte bei einem pong spiel so viele fps haben, das man den ball nur 6pixel bewegen muss, und da so ein pad bestimmt dicker als 6pixel ist, müsste man auch immer auf kollision prüfen. bei 60fps macht das dann 360 pixel bewegung pro sekunde, das sollte dicke reichen, oder??? Ist doch schön schnell... |
||
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/ |
![]() |
SpionAtom |
![]() Antworten mit Zitat ![]() |
---|---|---|
Goodjee hat Folgendes geschrieben: @kabelbinder:
man sollte bei einem pong spiel so viele fps haben, das man den ball nur 6pixel bewegen muss, und da so ein pad bestimmt dicker als 6pixel ist, müsste man auch immer auf kollision prüfen. bei 60fps macht das dann 360 pixel bewegung pro sekunde, das sollte dicke reichen, oder??? Ist doch schön schnell... Das mag ja alles stimmen, aber aus der Sicht eines Informatikers ist es immer schöner die Grafikebene von der Berechnungsebene zu trennen. Dadurch wird der Code übersichtlicher und viel besser ausbaufhäig und lässt sich bequemer warten. Es ist vielleicht nicht immer der einfachste Weg, aber die enstehenden Vorteile "meiner" Methode sind es wert. |
||
os: Windows 10 Home cpu: Intel Core i7 6700K 4.00Ghz gpu: NVIDIA GeForce GTX 1080 |
![]() |
x-pressive |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wenn ich solche Kollisionsabfragen nutze, rechne ich die Geschwindigkeit des Objekts immer in der Abfrage mit ein und hatte bisher eigentlich keine Probleme damit:
Code: [AUSKLAPPEN] ; BALL PASSIERT LINKEN SCHLÄGER?
If (ball_posx - ball_speedx) < schlaeger_posx Then ; BALL AUF SELBER HÖHE WIE SCHLÄGER? If (ball_posy > schlaeger_posy) And (ball_posy < schlaeger_posy + schlaeger_height) Then ; DANN SCHLÄGER GETROFFEN ball_posx = schlaeger_posx ball_speedx = ball_speedx * -1 ball_speedy = ball_speedy * -1 Else ; BALL IM AUS - GAME OVER End If End If Müsste doch funktionieren -oder habe ich einen Denkfehler? ![]() |
||
• BLITZ SHOWCASE:
PARTICLE CANDY • PARTICLE CANDY FOR iPHONE • SPRITE CANDY • DON'T GET ANGRY! 2-3 • CLICK CLACK XL |
![]() |
Goodjee |
![]() Antworten mit Zitat ![]() |
---|---|---|
aber es ist nur ein pong spiel....und meine kollision ist viel einfacher zu verstehen und viel simpler....
warum manuell alle punkte dazwischen testen, es ist doch nur wichtig ob der ball in der nähe ist.... |
||
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/ |
![]() |
x-pressive |
![]() Antworten mit Zitat ![]() |
---|---|---|
Nicht-skalierbare Lösungen sind niemals ein guter Programmierstil. Und eine Lösung, die erstens nur eine bestimmte Ballgeschwindigkeit erlaubt und zweitens auch noch eine Mindestframeanzahl voraussetzt ist einfach nur *SCHHROTT* und gehört in die Beginner's Coner.
Genauso idiotisch ist es, bei solchen Kinkerlitzchen mit langsamen Kollisionsabfragen herumzuwedeln. Die spart man sich besser für Momente, wo man sie wirklich braucht. Till, hier hast du dein Pong-Spiel -komplett. Du musst einfach nur die Ballgeschwindigkeit bei den Abfragen mit einbeziehen. Folgendes Beispiel funktioniert mit ALLEN Geschwindigkeiten und jeder Framerate: Code: [AUSKLAPPEN] Graphics 640,480,0,2 : SetBuffer BackBuffer() : SeedRnd MilliSecs()
Global y# = 320 Global x# = 240 Global w% = 8 ; BALL GRÖSSE Global sx# = Rand(3,9) ; BALL SPEED X Global sy# = Rand(3,9) ; BALL SPEED Y Global batx# = 5 ; SCHLÄGER ABSTAND VON RAND Global baty# = 240 ; SCHLÄGER (BAT) POSITION Global bath# = 75 ; SCHLÄGER HÖHE Global batw# = 16 ; SCHLÄGER BREITE While Not KeyDown(1) CLS Rect x, y, w, w, 1 ; BALL ZEICHHNEN Rect batx,baty,batw,bath,1 ; SCHLÄGER L ZEICHNEN Rect (640-batx)-batw,baty,batw,bath,1 ; SCHLÄGER R ZEICHNEN ; BALL BEWEGEN x = x + sx : y = y + sy ; SCHLÄGER BEWEGEN If KeyDown(200) And baty > 0 Then baty = baty - 10 If KeyDown(208) And baty < 480-bath Then baty = baty + 10 ; RÄNDER UNTEN & OBEN APRALLEN If y - sy < 0 Then y = 0 : sy = sy * -1 If y + sy > 480 Then y = 480-w : sy = sy * -1 ; BALL GANZ LINKS ODER RECHTS? If x - sx < batx + batw Or x + sx > (640-batx)-batw ; SCHLÄGER GETROFFEN? If y > baty And y < baty + bath Then sx = sx * -1 sy = sy * -1 ; BALL AN SCHLÄGER SETZEN If x < 320 Then x = batx + batw If x > 320 Then x = (640-batx)-batw ; BALL IM AUS! RESET Else x = 320 : y = 240 End If End If Flip 1 Wend |
||
• BLITZ SHOWCASE:
PARTICLE CANDY • PARTICLE CANDY FOR iPHONE • SPRITE CANDY • DON'T GET ANGRY! 2-3 • CLICK CLACK XL |
![]() |
SpionAtom |
![]() Antworten mit Zitat ![]() |
---|---|---|
x-pressive hat Folgendes geschrieben: Genauso idiotisch ist es, bei solchen Kinkerlitzchen mit langsamen Kollisionsabfragen herumzuwedeln. Die spart man sich besser für Momente, wo man sie wirklich braucht. @x-pressive Irgendwie hast du ja Recht... ![]() @Beispielcode Allerdings musst du bei deiner Methode noch die "zukünftige" Position der Pads mit einberechnen. Aber wie bereits gesagt, es ist nur ein Pong. |
||
os: Windows 10 Home cpu: Intel Core i7 6700K 4.00Ghz gpu: NVIDIA GeForce GTX 1080 |
![]() |
x-pressive |
![]() Antworten mit Zitat ![]() |
---|---|---|
Code: [AUSKLAPPEN] @Beispielcode
Allerdings musst du bei deiner Methode noch die "zukünftige" Position der Pads mit einberechnen. Natürlich, aber war ja nur ein schnelles Beispiel. Es geht ja nicht darum, daß die "Punkt-Methode" langsam wäre, sondern darum, daß sie absolut sinnlos und überflüssig ist, wenn es eine simple und effiziente Lösung gibt. Man sollte schliesslich versuchen, Dinge mit jedem einzelnen Projekt besser zu machen und nicht ewig bei der selben Methode bleiben, nur weil sie halt einmal funktioniert hat -Traditionen" gehören in den Trachtenverein ![]() |
||
• BLITZ SHOWCASE:
PARTICLE CANDY • PARTICLE CANDY FOR iPHONE • SPRITE CANDY • DON'T GET ANGRY! 2-3 • CLICK CLACK XL |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group