 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
d1rty.h4rry

Anmeldungsdatum: 05.10.2006 Beiträge: 116 Wohnort: Cassel
|
Verfasst am: 07.10.2007, 17:47 Titel: 2D Kollision |
|
|
Hi FB und QB Community^^
da ich in der suche nix anständiges gefunden habe was mir hilft habe ich mich dazu durchgerungen das thema halt neu zu posten^^
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..
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  _________________ "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  |
|
Nach oben |
|
 |
PMedia
Anmeldungsdatum: 14.08.2006 Beiträge: 2847
|
Verfasst am: 08.10.2007, 20:47 Titel: |
|
|
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 |
|
 |
Dr. Bakterium
Anmeldungsdatum: 13.09.2007 Beiträge: 13
|
Verfasst am: 10.10.2007, 22:19 Titel: |
|
|
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 |
|
 |
d1rty.h4rry

Anmeldungsdatum: 05.10.2006 Beiträge: 116 Wohnort: Cassel
|
Verfasst am: 11.10.2007, 21:22 Titel: |
|
|
Vielen Dank an euch für die Antworten
@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 wie berechne ich die verlängerte flugrichtung 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 hab da keine Peilung xD
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
ein bisschen mathe über wär wohl auch net schlecht
D!RTY 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  |
|
Nach oben |
|
 |
dreael Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 2529 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 11.10.2007, 22:53 Titel: |
|
|
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 |
|
 |
d1rty.h4rry

Anmeldungsdatum: 05.10.2006 Beiträge: 116 Wohnort: Cassel
|
Verfasst am: 13.10.2007, 20:30 Titel: |
|
|
@dreal: 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 da muss ich erstmal durchsteigen.. aba wunderbar das proggi hilft mir auf jeden fall
D!rTy 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  |
|
Nach oben |
|
 |
Dr. Bakterium
Anmeldungsdatum: 13.09.2007 Beiträge: 13
|
Verfasst am: 15.10.2007, 20:16 Titel: |
|
|
Danke für den Willkommensgruß
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
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 |
|
 |
|
|
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.
|
|