Ball-Wall Kollision (rollen)

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

ToeB

Betreff: Ball-Wall Kollision (rollen)

BeitragDi, Nov 03, 2009 17:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Also ich wollte mal testen wie man 2D bälle mit einer Wand kollidieren lassen kann. Dazu habe ich mir gedacht, stell dir eine Linie vor, die beim Ball mitellpunkt startet und die länge von Radius+Speed hat. Mit dieser linie werden jetzt die Wände geprüft, die auch nur aus linien bestehen. Dann, bei kollision bzw. überschneidung der linien wird der Ball vom Schnittpunkt aus im 90° winkel mit dem abstand des Radiuswieder zurückgesetzt. Dadurch fliegt der "Ball" nicht durch die mauer und gleitet auch schön herab. Nur was mich dabei stört : Der Ball beschleunigt nicht, und ist, wenn er runterfällt auf einmal zu schnell weg, da ja trotzdem die geschwindigkeit dzugerechnet wird. Wie kann ich nun die Geschwindigkeit berechnen ?

Hier der code :
Code: [AUSKLAPPEN]
Graphics 800,600,16,2
SetBuffer BackBuffer()

Type l
   Field x1,y1
   Field x2,y2
   Field w,ab#
End Type

Type b
   Field x#,y#,sx#,sy#
   Field r#
End Type 

Global Grav_Y# = 0.1
Global intersection_x# ,intersection_y#

Global timer = CreateTimer(60)

al(100,100,700,500)

Repeat
   If akt.l <> Null
      akt\x2 = MouseX()
      akt\y2 = MouseY()
      akt\w = ATan2(akt\y2-akt\y1,akt\x2-akt\x1)
      akt\ab# = Sqr((akt\x2-akt\x1)^2+(Akt\y2-akt\y1)^2)
   EndIf
   If MouseHit(2)
      If akt.l = Null
         akt.l = New l
         akt\x1 = MouseX()
         akt\y1 = MouseY()
      ElseIf akt.l <> Null
         
         akt = Null
      EndIf
   EndIf
   If MouseHit(1) Then
      tmp.b = New b
      tmp\x = MouseX()
      tmp\y = MouseY()
      tmp\sy = -1
      tmp\sx = Rnd(-1,1)
      tmp\r = 5
   EndIf

   LockBuffer BackBuffer()
   For l.l = Each l
      Line l\x1,l\y1,l\x2,l\y2
      x# = l\x1+Cos(l\w) * (l\ab/2.0)
      y# = l\y1+Sin(l\w) * (l\ab/2.0)
      Line x,y,x+Cos(l\w-90)*10,y+Sin(l\w-90)*10
   Next
   UnlockBuffer BackBuffer()
   
   For tmp.b = Each b
      newx# = tmp\x + tmp\sx
      newy# = tmp\y + tmp\sy
      tmp\sy = tmp\sy + Grav_y
      sw# = ATan2(tmp\sy,tmp\sx)
      sa# = Sqr(tmp\sx*tmp\sx+tmp\sy*tmp\sy)
      For l.l = Each l
         If LineIntersect(tmp\x,tmp\y,tmp\x+Cos(sw)*(sa+tmp\r),tmp\y+Sin(sw)*(sa+tmp\r),l\x1,l\y1,l\x2,l\y2) Then
            newx = intersection_x#+Cos(l\w-90)*tmp\r
            newy = intersection_y#+Sin(l\w-90)*tmp\r
            ;HIER MUSS DIE GESCHWINDIGKEIT BERECHNET WERTEN ! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
         EndIf
      Next
      tmp\x = newx
      tmp\y = newy
      Oval tmp\x-tmp\r,tmp\y-tmp\r,tmp\r*2,tmp\r*2,0
   Next
   WaitTimer(timer)
   Flip 0
   Cls
Until KeyHit(1)
End

Function al(x1,y1,x2,y2)
   l.l = New l
   l\x1 = x1
   l\x2 = x2
   l\y1 = y1
   l\y2 = y2
   l\w = ATan2(l\y2-l\y1,l\x2-l\x1)
   l\ab# = Sqr((l\x2-l\x1)^2+(l\y2-l\y1)^2)
End Function

Function LineIntersect(ax#, ay#, bx#, by#, cx#, cy#, dx#, dy#)
   rn# = (ay#-cy#)*(dx#-cx#) - (ax#-cx#)*(dy#-cy#)
   rd# = (bx#-ax#)*(dy#-cy#) - (by#-ay#)*(dx#-cx#)
   If rd# = 0
      Return False
   Else
      sn# = (ay#-cy#)*(bx#-ax#) - (ax#-cx#)*(by#-ay#)
      intersection_ab# = rn# / rd#
      intersection_cd# = sn# / rd#
      intersection_x#  = ax# + intersection_ab#*(bx#-ax#)
      intersection_y#  = ay# + intersection_ab#*(by#-ay#)
      If intersection_ab#>0 And intersection_ab#<1 And intersection_cd#>0 And intersection_cd#<1 Then Return True
   EndIf
End Function


mfg ToeB
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art
SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek
Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt!

Midimaster

BeitragDo, Nov 19, 2009 11:07
Antworten mit Zitat
Benutzer-Profile anzeigen
theoretisch ist es doch so, dass die Linie dafür sorgt, dass die Beschleunigung, die der Ball hat umgelenkt wird.

Hier ist Dein Denkfehler. Es sieht nur so aus, als ob der Ball nur eine Beschleunigung nach unten haben könnte. Wenn er fällt ist BeschleunigungX natürlich trotzdem da, aber eben im Moment 0. Auf einer waagrechten Ebene würde der Ball wegen seiner BeschleunigungY nach oben umkehren, bis ihn die Gravitation wieder zurückholt.

BeschleunigungY=BeschleunigungY+Gravitation

Auf der 45° Ebene würde der BeschleunigungsVektor komplett in die X-Achse umgekehrt. Die BeschleunigungX wäre gleich BeschleunigungY. Die BeschleunigungY wäre momentan 0. Wird aber durch die Gravitation wieder ansteigen. Jedes Mal, wenn nun der Ball wieder die Ebene berührt, wird dieser Teil zu BeschleunigungX addiert. Dadurch kommt es zu einem Tempoanstieg insgesamt.

Für beliebige Ebenenwinkel musst Du im Moment der Kollision denn aktuellen Beschleunigungsvektor in Grad berechnen, dann für ihn die Winkeländerung bei Kollision bestimmen und über sin/cos die beiden Anteile BeschleunigungX und BeschleunigungY bestimmen. Dann geht das ganze von vorne los.

Kann sein, dass dann Dein Ball ein paar mal hüpft, bevor er abrollt. Aber das wäre sehr realistisch. Kann man dadurch verbessern, dass die Ebene Energie schluckt. Also nicht mehr der gesamte Anteil des Vektors zu den Beschleunigungen addiert wird.

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group