Pong - Pad Kollision

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

 

Till P.

Betreff: Pong - Pad Kollision

BeitragSo, März 12, 2006 22:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Halli Hallo, ich bin wieder da!

Und ich hab auch gleich eine Frage mitgebracht: Laughing

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!
Wink

mfG
Till

SpionAtom

BeitragSo, März 12, 2006 22:50
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Laughing

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

BeitragMo, März 13, 2006 15:27
Antworten mit Zitat
Benutzer-Profile anzeigen
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/

Kabelbinder

Sieger des WM-Contest 2006

BeitragMo, März 13, 2006 23:02
Antworten mit Zitat
Benutzer-Profile anzeigen
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.

BeitragMo, März 13, 2006 23:21
Antworten mit Zitat
Benutzer-Profile anzeigen
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! Wink

Danke nochmal!

Goodjee

BeitragDi, März 14, 2006 15:56
Antworten mit Zitat
Benutzer-Profile anzeigen
@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

BeitragDi, März 14, 2006 18:02
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMi, März 15, 2006 14:38
Antworten mit Zitat
Benutzer-Profile anzeigen
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? Wink
• BLITZ SHOWCASE:
PARTICLE CANDY • PARTICLE CANDY FOR iPHONE • SPRITE CANDY • DON'T GET ANGRY! 2-3 • CLICK CLACK XL

Goodjee

BeitragMi, März 15, 2006 15:42
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMi, März 15, 2006 16:24
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMi, März 15, 2006 16:55
Antworten mit Zitat
Benutzer-Profile anzeigen
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... Embarassed Und blöderweise habe diese, deine Methode auch schon genutzt. Ich war wohl nur abgelenkt durch mein Jump&Run-Spiel, weil ich da das selbe Problem zu bewältigen habe. Trotzdem finde ich die Punkte-Methode gar nicht so langsam.

@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

BeitragMi, März 15, 2006 18:25
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Wink
• BLITZ SHOWCASE:
PARTICLE CANDY • PARTICLE CANDY FOR iPHONE • SPRITE CANDY • DON'T GET ANGRY! 2-3 • CLICK CLACK XL

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group