Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

2D Kollision

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
d1rty.h4rry



Anmeldungsdatum: 05.10.2006
Beiträge: 116
Wohnort: Cassel

BeitragVerfasst am: 07.10.2007, 17:47    Titel: 2D Kollision Antworten mit Zitat

Hi FB und QB Community^^ lächeln

da ich in der suche nix anständiges gefunden habe was mir hilft habe ich mich dazu durchgerungen das thema halt neu zu posten^^ lächeln

Ich bin gerade dabei ein simples Game zu proggen wo man ein Kugel in Jump'n'Run art durch ein Levbel Steuern muss... es gibt normale Plattformen, Fahrstühle, Plattformen aus Eis(wo man halt Rutscht), Plattform auf denen man beispielsweis nicht springen oder höher springen kann, Ventilatoren die einen in eine Richtung Pusten u.s.w.. lächeln

Ich habe lediglich das problem das ich diese Plattformen, damit die Kollisions erkennung Funktioniert, nur Waagerecht oda eben Senkrecht platzieren kann...

Ich habe mir überlegt: wenn ich schräge erstellen will könnte ich das doch über dreiecksberechnungen lösen.. die Frage ist nur wie?

Code:

          /     Hier möchte ich beispielsweis das dass Objekt nicht die Schräge "c" überschreitet
        / |     "b" und "a" soll es beispielsweise aber überschreiten dürfen falls es von der anderen seite kommt
     c/   |b    Aber auch in dem Fall es kommt von der andren seite soll es die schräge "c" nicht überschreiten
    /     |
  /_______|
         a


Das die Entsprechende Kugel die Schräge herunter rutsch oder rollt kann mann ja berechen in dem man abfragt wie "schräg" das dreieck von den Winkeln her ist und dann eine entsprechende seitwärts bewegung ausführt...

Ich hoffe jemand hat für mich eine passende lösung parat^^

vielen dank schonmal im Vorraus lächeln
_________________
"Das Fernsehen ist so etwas wie eine geistige Neutronenbombe, das Gehirn wird weggestrahlt. Nur der Kopf bleibt da!" -Olliver Kalkhofe
-> http://fernsehkritik.tv/tv-magazin/
"Wenn alle Stricke reißen, dann häng ich mich auf", Karl Kreiss lächeln
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden MSN Messenger
PMedia



Anmeldungsdatum: 14.08.2006
Beiträge: 2847

BeitragVerfasst am: 08.10.2007, 20:47    Titel: Antworten mit Zitat

Warum Winkelberechnung?
Prozentrechnung tuts doch auch.

Zitat:

(X1;Y1) und (X2;Y2) sind die beiden Punkte der Schräge

X1 == Niedrigste X
X2 == Höchste X
Y1 == Niedrigste Y
Y2 == Höchste Y


Abstand ermitteln:
AX = X2 - X1
AY = Y2 - Y1

Crashpunkt ermitteln:
PX = X1 + (AX / 100 * P)
PY = Y1 + (AY / 100 * P)

(PX;PY) gibt dann den jeweiligen Punkt an, wo die Kollision geprüft werden muss. P ist ein Wert von 0 - 100 (Nat. anpassbar durch Änderungen am Divisor) sein



(Aja der Text ist von mir, Zitat nur um es ein wenig hervorzuheben)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Dr. Bakterium



Anmeldungsdatum: 13.09.2007
Beiträge: 13

BeitragVerfasst am: 10.10.2007, 22:19    Titel: Antworten mit Zitat

Ich würde den Ball über Vektoren steuern, weil man so beliebige Kräfte zu einer Kraft zusammenrechnen kann.

Beispiel: Du hast deinen Ball, der sich in eine beliebige Richtung zwischen 0° und 360° bewegen kann, entsprechend eines Pfeiles, der in eine Richtung zeigt. Weiterhin hast du einen Wert für die Geschwindigkeit, in der sich der Ball pro Zeiteinheit bewegt. Bildlich repräsentiert würde das durch die Länge dieses Pfeiles. Fertig ist der Bewegungsvektor.

Alle anderen Vektoren wie Schwerkraft, Seitenwinde werden einfach zu einem Ergebnisvektor zusammengerechnet und schon weiß man, wo der Ball in der nächsten Zeiteinheit sein soll. Die Kollisionserkennung müßte man selbst in die Hand nehmen, einfach indem man berechnet, ob sich dieser Vektor z. B. mit einer Plattform-Linie schneidet und dann den Vektor quasi wie einen Lichtstrahl reflektieren läßt.
Ohne etwas Geometrie und Physik gehts also nicht, wenn es realistisch aussehen soll. Soviel Formeln braucht man aber auch wieder nicht. Eine Formelsammlung wäre trotzdem hilfreich.

Dein Problem mit der Schräge wäre dann automatisch gelöst weil die Vektoraddition sowie die Schwerebeschleunigung universell ist.

Hier noch ein Beispiel für Schnittpunktberechnung für kartesischen Koordinaten:

1. Linie von 1/1 nach 10/5
2. Linie von 4/10 nach 8/2

m = (y2-y1)/(x2-x1), daraus folgt m1 = (5-1)/(10-1) = 4/9 = 0,4444 und m2 = (2-10)/(8-4) = -8/4 = -2

Jetzt berechnen wir noch den sog. t-Abschnitt, also die y-Koordinate des Geradenpunktes wenn x = 0 ist, gemäß der allgemeinen Geradengleichung y = m * x + t
Wir kennen also den Steigungsfaktor m, für x und y nimmt man einfach einen beliebigen Punkt, der auf der Geraden liegt wie z. B. den Anfangspunkt der 1. Linie, 1/1. Daraus folgt:

1 = 0,4444 * 1 + t
t = 0,5555

Die Geradengleichung für die 1. Linie lautet also: y = 0,4444 * x + 0,5555
... und für die 2. Linie: y = -2 * x + 18

Für den Schnittpunkt setzt man nun beide Gleichungen gleich und lößt nach x auf:
0,4444 * x + 0,5555 = -2 * x + 18
x = 7,1365

und das wiederum eingesetzt in irgendeine der obigen Geradengleichungen ergibt für Y den Wert 3,7270. Somit ist der Schnittpunkt bzw. Kollisionspunkt auf Koordinate 7,14 / 3,72.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
d1rty.h4rry



Anmeldungsdatum: 05.10.2006
Beiträge: 116
Wohnort: Cassel

BeitragVerfasst am: 11.10.2007, 21:22    Titel: Antworten mit Zitat

Vielen Dank an euch für die Antworten lächeln

@PMedia: Habs mit dieser Variante mal versucht das sah in etwa so aus
Code:

'Auszug aus Bounce.bas
'#####################
   ...
   ...
   ...
    With Linex(Lines)
       
        Select Case .Func
       
          Case Special
            AX= .X2n - .Xn
            AY= .Y2n - .Yn

            For P = 0 To 100
               PX = .Xn + (AX / 100 * P)
               PY = .Yn + (AY / 100 * P)
'===========> "If Y = PY And X = PX Then SPD=-SPD" Oder  "If Y < PY And X < PX Then SPD=-SPD"         
            next
              
            .Ys+=.DL
            If .Ys > 245 Then .Dl=-.Dl
            If .Ys < 10 Then .Dl=-.Dl
              
            LinePos(Lines).X=.Xn
            LinePos(Lines).Y=.Yn
            LinePos(Lines).Xz=.X2n
            LinePos(Lines).Yz=.Y2n
            LinePos(Lines).C=Rgb(50,80,Int(.Ys))
              
           Case Ice
   ...
   ...
   ...
'#####################


Jedoch ist Die Abfrage (jeden punkt einzeln abzutasten) zu ungenau falls der Ball oder die Kugel die Geschwindigkein Von 1 überschreitet da hier leicht der "eine" pixel übersprungen wird, weil die Plattform nur einen Pixel dick ist... wobei man es hier auch umformen könnte indem man z.B 10 pixel darunter, Drüber, links und rechts abfragen lässt... hierdurch wird die kollision etwas genauer jedoch wird sie auch aufwendiger...

@Dr. Bakterium:
Ersteinmal willkommen in der FB Community^^
das ist dein 2. Beitrag^^

Diese Variante der Vektoren berechnung hab ich schon einmal eingesetzt

ich hab da mal ein bisschen mit Paint rumgespielt und was gekritzelt... denn ich konnte deiner Strahlen berechnung nicht so ganz folgen...

Ich nehme mal an mit Linie 1 und 2 meinst du die Verlängerte Flugrichtung und die linie des untergrundes ansonsten weis ich nicht was die 2 linien bringen... Da weis ich bloß auch wieder nicht happy wie berechne ich die verlängerte flugrichtung happy Ich brauche dann ja wieder 2 Koordinaten eine wäre in dem Fall die XY pos des Balles und die andere könnte man ja so 100 Pixel entfernt berechnen lassen bloß wie traurig hab da keine Peilung xD lächeln

Und noch eine Frage wie kann man Vektorgeschwindigkeiten und Winkel zu einem Gesamt Vektor addieren? ich hatte damals ein kleines spiel wo objekte sich mit einer Bestimmten Geschwindigkeit in einen bestimmten Winkel bewegen sollten, das funzte auch bloß dann wollte ich kräfte wie schwerkraft oder fliehkraft einbauen... bei der schwerkraft kamm ich bei "Y+=Uspd" und "Uspd+=(Gravity/100)" nicht sehr weit.. es endete so das die objekte immer in einem großen Bogen zu boden gingen sobalt eine geringe beschleunigung nach links oder rechts auftrat... was sehr unreal aussah... und da sich bei der schwerkraft die geschwindigkeit nach unten ständig erhöht kann man auch nur einen gesamtvektor berechnen der sich jede millisekunde ändert.. was ja auch ganz normal ist^^

Um auf die Linien zurück zu kommen wenn ich hier an die schwerkraft und den abprall an einer geraden denke muss ja zum einen die geschwindigkeit leicht vermindert werden (wegen energie abgabe) und zusätzlich muss (nach dem reflextions prinzip) die kugel in einem entprechendem Winkel von einer plattform abprallen in dem auch der Winkel der Plattform enthalten ist... das sind für mich ziemlich viele Faktoren die die Kugel betreffen...

Kennt jemand vllt ein gutes tutorial zu dem Vektorproblem? wär ganz net
...
Wie auch immer ich danke euch nochmal und werde mich nun intensiv mit vektoren beschäftigen müssen happy
ein bisschen mathe über wär wohl auch net schlecht happy

D!RTY böse HaRrY
_________________
"Das Fernsehen ist so etwas wie eine geistige Neutronenbombe, das Gehirn wird weggestrahlt. Nur der Kopf bleibt da!" -Olliver Kalkhofe
-> http://fernsehkritik.tv/tv-magazin/
"Wenn alle Stricke reißen, dann häng ich mich auf", Karl Kreiss lächeln
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden MSN Messenger
dreael
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 2529
Wohnort: Hofen SH (Schweiz)

BeitragVerfasst am: 11.10.2007, 22:53    Titel: Antworten mit Zitat

Vielleicht hilft an dieser Stelle

http://www.dreael.ch/Deutsch/Download/Billard-Simulation.html

aus meiner Sammlung weiter. Dort kommen solche Probleme wie Kollisionsberechnung und Impulssatz voll zur Anwendung. Portierung in FreeBasic müsste eigentlich problemlos sein, wenn nicht sogar 1:1 lauffähig.
_________________
Teste die PC-Sicherheit mit www.sec-check.net
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
d1rty.h4rry



Anmeldungsdatum: 05.10.2006
Beiträge: 116
Wohnort: Cassel

BeitragVerfasst am: 13.10.2007, 20:30    Titel: Antworten mit Zitat

@dreal: happy lächeln Danke für die Antwort..

Dein Proggy kann echt genau dass, was ich suche... immerhin und das konnte es schon 1999 xD wunderbar jetz muss ich mich nur etwas einarbeiten, da es ja schon sehr komplex ist.

Die protierung auf FB war auch nicht einfach ich habs aber hinbekomm... ein paar variblen waren nicht explizit definiert und deine Screen-Pcopy geschichten musste ich umschreiben... und mit der Linien Zeichen routine war bei der 1.Version ein bug in FB aba das is jetz auch OK..

Das prog verwendet so viele Formeln happy da muss ich erstmal durchsteigen.. aba wunderbar das proggi hilft mir auf jeden fall

D!rTy happy H4RrY
_________________
"Das Fernsehen ist so etwas wie eine geistige Neutronenbombe, das Gehirn wird weggestrahlt. Nur der Kopf bleibt da!" -Olliver Kalkhofe
-> http://fernsehkritik.tv/tv-magazin/
"Wenn alle Stricke reißen, dann häng ich mich auf", Karl Kreiss lächeln
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden MSN Messenger
Dr. Bakterium



Anmeldungsdatum: 13.09.2007
Beiträge: 13

BeitragVerfasst am: 15.10.2007, 20:16    Titel: Antworten mit Zitat

Danke für den Willkommensgruß lachen

Na, da hast du schon so ziehmlich alles fix und fertig, was du brauchst.
Die Schwerkraft nimmt quadratisch zur Entfernung ab, vielleicht war das der Fehler in deiner Formel. Das mit dem Winkel war doof von mir, weil es geht auch ganz gut ohne indem man einfach alle DX und DY addiert.
Hier ein kleines Beispiel anhand der Erde, wie sie um die Sonne kreist:


Ohne Sonne würde die Erde im kartesischen Koordinatensystem schnurgerade senkrecht nach oben fliegen, also DX = 0 und DY = 1, was Vektor V1 entspricht. Die Gravitation zieht die Erde aber zur Sonne hin, Mittelpunkt zu Mittelpunkt, was durch den Vektor V2 (DX = 1 und DY = 0) symbolisiert wird. Man addiert nun einfach sämtlich DX miteinander und macht mit den DY dasselbe und erhält so den Endvektor V, mit dem die Kugel dann tatsächlich bewegt wird (x += dx und y += dy).


Hier nun die Kollision. Du kennst sicher noch den Spruch "Eintrittswinkel = Austrittswinkel". Hierzu brauchst du die Schnittpunktberechnung von oben. Du zerlegst den langen Vektor in 2 Teilstücke, einmal von der aktuellen Kugelposition bis zum Schnittpunkt und zum anderen vom Schnittpunkt zur Endposition. Wobei Länge(Austrittsvektor) = Länge(Ursprungsvektor) - Länge(Eintrittsvektor) - Energieverlust(Hindernis).
Energieverlust ist natürlich optional.
Das eigentliche Abprallen sieht mal also garnicht, außer du machst einen zeichnerischen Zwischenschritt. Auf alle Fälle brauchst du den Schnittpunkt, schon alleine um die Winkel zu berechnen.

So, und hier noch ein kleines Gravitationsbeispiel, in dem sich dutzende Kugeln gleichzeitig anziehen. Die Kollisionsauswertung ist vereinfacht, ohne Schnittpunktberechnung, weshalb sie nicht 100% korrekt funktioniert. Aber für dieses Beispiel dürfte es ausreichend sein. Nur hin und wieder werden manchmal Kugel extrem schnell dadurch "rausgekegelt", wenn sie sich zu schnell bewegen. Ist ungefähr so wie wenn man einer Radarfalle davonfährt grinsen

Code:

'
' Gravity 1.0
' by Dr. Bakterium
'
#Include "crt/string.bi"

Const AnzahlPlaneten = 55
Const G = 0.0667259/2
Const PI As Double = 3.1415926535897932

Type Planet
   As Double x,y,dx,dy,m
   As UByte Geloescht
End Type

Dim Shared Planeten(1 To AnzahlPlaneten) As Planet
Dim Shared PlanetenNeu(1 To AnzahlPlaneten) As Planet
Dim As Double Anziehung,w,r
Dim As UShort i,j
Dim As UByte t
Dim As String Taste

Function Radius(Flaeche As Double) As Double
   Return Sqr(Flaeche/PI)
End Function
Function DifferenzX(vonPlanet As UShort,nachPlanet As UShort) As Long
   Return Planeten(nachPlanet).x-Planeten(vonPlanet).x
End Function

Function DifferenzY(vonPlanet As UShort,nachPlanet As UShort) As Long
   Return Planeten(nachPlanet).y-Planeten(vonPlanet).y
End Function

Function DistanzQuadrat(vonPlanet As UShort,nachPlanet As UShort) As Double
   return DifferenzX(vonPlanet,nachPlanet)^2+DifferenzY(vonPlanet,nachPlanet)^2
End Function

sub Kollision(vonPlanet As UShort,nachPlanet As UShort)
   Dim As Double MassenSumme,vonAnteil,nachAnteil

   MassenSumme = Planeten(vonPlanet).m+Planeten(nachPlanet).m
   If Sqr(DistanzQuadrat(vonPlanet,nachPlanet)) <= Radius(MassenSumme) Then
      vonAnteil = Planeten(vonPlanet).m / MassenSumme / 2
      nachAnteil = Planeten(nachPlanet).m / MassenSumme / 2
      With PlanetenNeu(vonPlanet)
         .dx = (Planeten(vonPlanet).dx * vonAnteil) + (Planeten(nachPlanet).dx * nachAnteil)
         .dy = (Planeten(vonPlanet).dy * vonAnteil) + (Planeten(nachPlanet).dy * nachAnteil)
         .m = MassenSumme
      End With
      '' Bei Kollision: 1. Planet wird schwerer, 2. Planet wird gelöscht
      PlanetenNeu(nachPlanet).Geloescht = 1
      Planeten(nachPlanet).Geloescht = 1
   End If
End sub


'' Hauptschleife

do

'' Planeten verteilen
   Randomize Timer,1
   For i = 1 To AnzahlPlaneten
      With Planeten(i)
         w = Rnd*PI*2
         r = Rnd*200
         .x = 320 + Cos(w)*r
         .y = 240 - Sin(w)*r
         .dx = 0
         .dy = 0
         .m = 3
         .Geloescht = 0
      End With
   Next

'' Ersatz für  PlanetenNeu = Planeten
   memcpy(@PlanetenNeu(1),@Planeten(1),Len(Planeten(1))*AnzahlPlaneten)

   Screen 12,4,2

'' Schleife für Planetenbewegungen und -kollision
   Do
      ScreenSet t,1-t
      t = 1 - t
      cls
      For i = 1 To AnzahlPlaneten
         If Planeten(i).Geloescht = 0 then
            With Planeten(i):Circle (.x,.y),Radius(.m),(.m Mod 14)+1,,,,F:End With
            With PlanetenNeu(i)
               '' Bewegungsschleife
               For j = 1 To AnzahlPlaneten
                  If j <> i And Planeten(j).Geloescht = 0 Then
                     Anziehung = G * (Planeten(i).m * Planeten(j).m / DistanzQuadrat(i,j))
                     .dx += DifferenzX(i,j) * Anziehung
                     .dy += DifferenzY(i,j) * Anziehung
                  End If
               Next
               .x += .dx
               .y += .dy
               '' Kollisionsschleife
               For j = 1 To AnzahlPlaneten
                  If j <> i And Planeten(j).Geloescht = 0 Then
                     Kollision(i,j)
                  End If
               Next
            End With
         End if
      Next
   
      Taste = InKey
      '' a,s,w,y steuert den sichtbaren Ausschnitt (links, recht, rauf, runter)
      '' Leertaste = neues Szenario
      '' x = Programm beenden
      Select Case Taste
         Case "a":For i = 1 To AnzahlPlaneten:PlanetenNeu(i).x+=100:next
         Case "s":For i = 1 To AnzahlPlaneten:PlanetenNeu(i).x-=100:next
         Case "w":For i = 1 To AnzahlPlaneten:PlanetenNeu(i).y+=100:next
         Case "y":For i = 1 To AnzahlPlaneten:PlanetenNeu(i).y-=100:next
      End select
      memcpy(@Planeten(1),@PlanetenNeu(1),Len(Planeten(1))*AnzahlPlaneten)
      Sleep 30
   
   Loop Until Taste = " " Or Taste = "x"

Loop Until Taste = "x"
end
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz