• Hi Leute,

    es ist so weit, nachdem meine Version 2 der Physik Engine so gut angekommen ist, hatte ich die Tage die Motivation eine Version 3 zu schreiben. Diese ist nun viel robuster um unterstützt Positionkorrektur, sodass man ohne Probleme mit Schwerkraft arbeiten kann. Außerdem fangen Körper die sich länger nicht bewegen an zu schlafen, sodass sie Leistung sparen. Aber seht selbst:

    Edit Version 3.1: Ich habe die Version jetzt dahin gebracht, wo Version 3.0 schon sein sollte. Man kann nun ohne Problem Objekte stapeln ohne Fehler, mit Reibung und ohne das sich die Objekt durchdringen. Außerdem wurde die Kollisionhirarchie überarbeitet um die Performence zu steiern. Ich hoffe euch gefällt diese Version nun ;).

    Update: Performance verbessert und Opengl Rendering hinzugefügt, sowie weitere kleine Verbesserungen
    Update2: Bessere Kollisionserkennung, andere Kollisionsverarbeitung, Geschwindigkeitssteigerung, bessere Oberfläche, bessere Kollisionshierarchie, Reibung, Fehler behoben

    Download : autoit.de/wcf/attachment/16514/
    alte Version2: autoit.de/wcf/attachment/16377/
    alte Version: autoit.de/wcf/attachment/16237/

    autoit.de/wcf/attachment/16474/

    es GAB noch kleine Felher mit der Reibung, aber ich arbeite dran ;)

  • Mir sind mehre Sachen aufgefallen...

    Die Körper "Springen" manchmal auseinander.
    (Wenn mehrere Körper auf engem Raum sind springt öfters einer raus, ohne aber die Gruppe zu verlassen)

    Bei Gruppen herrscht starke Unruhe, so stark würde das in echt nicht wackeln.

    Wenn ich das Fenster eine kleine Weile festhalte wirds komisch.
    Dann sind die Positionen teilweise außerhalb der Begrenzung...
    Das liegt (vermutlich) daran, dass die Bewegung für die verlorene Zeit trotzdem ausgeführt wird ohne dabei die kollisionen zu überprüfen.

    Beim klick auf "E" zum löschen erhalte ich folgendes.

    Spoiler anzeigen
    Code
    If ($g_Polygons_Mass[$polygon_id] <> 0) Or ($g_Polygons_Tensor[$polygon_id] <> 0) Then
    If (^ ERROR

    lg
    M

  • Hi,

    danke für die Rückmeldung, wenn du das Fenster festhälst wird nichts berechnet. Lässt du es wieder los wird der nächste zeitschritt berechnet, das heißt die objekte machen einen satz und könnne sich durchdringen. Das kann ich aber noch ändern. Der andere Fehler ist mir auch schon aufgefallen, da muss ich auf jeden fall mal schauen woran das liegt. Ich arbeite gerade noch an einem opengl renderer.

    grüße Moritz

  • Jop. Das liegt daran, weil du die Zeit als Wert benutzt.
    Je niedriger die Framerate desto ungenauer die Kollisionen. (Zum Test kannst du ja mal ein Sleep(100) in dein Beispiel einbauen um es auf 7-8 FPS zu drücken. Dann sieht man, dass die Objekte große Überschneidungsbereiche haben ohne zu "kollidieren")

    Es ist besser intern einen Counter laufen zu lassen und den bei jedem Schleifendurchlauf um 1 zu erhöhen.
    Dann funktioniert die Kollisionskontrolle auf jedem Computer gleich.
    Ansonsten sind die Resultate nicht reproduzierbar...

    Edit:
    Und vermutlich verbessert sich damit auch diese "Unruhe".
    Die entsteht glaube ich durch eingeschaltete Gravitation im Zusammenspiel mit dem Bezug der Bewegung zur Zeit.
    Im Beispiel können Objekte minimal in den Boden eindringen, da die Zeit zwischen den Frames einen Freien fall bedeuten (wenn ich das richtig interpretiere).

  • Mars, ich weiß woran das liegt :D ich habe das extra so gemacht, damit die PhysicEngine bei jedem gleich schnell läuft. Ich denke ich werde aber noch die option einbauen, dass wenn der zeitschritt zu groß ist, zb.größer als 30ms, dass dann ein fester zeitschritt verwendet wird. Außerdem werde ich noch die option einbauen, die winkelgeschwindigkeit und lineare geschwindigkeit zu limitieren.

    aber danke für deine hilfe, wie gefällt dir diese version sonst so?

  • Im Prinzip gefällt sie mir sehr gut.
    Im Download fehlt ein "=" in PhysicEngine_3_Draw.au3 an pos 154.

    Das mit der Zeit ist aber gleichzeitig das größte Problem.
    Ein Programm muss unabhängig von der Ausführgeschwindigkeit zum gleichen Ergebnis kommen.

    Die verlorenen Kollisionen müssen nachberechnet werden.
    Dazu muss überprüft werden ob sich die Richtungsvektoren der einzelnen Objekte (unter berücksichtigung der Gravitation) treffen.
    Gibt es einen Treffer müssen alle betroffenen Objekte neu berechnet werden.
    Anschließend muss wieder überprüft werden, wieder kollidiert werden, usw usw.
    Bis man an Dem Zeitpunkt angekommen ist der Ausgegeben werden soll.

    Daaan ist es möglich diese Engine unabhängig vom System zu benutzen und äquivalente Ergebnisse zu erhalten. (glaube ich^^)

  • Das Problem ist, das die Engine zu langsam ist, um alle Kollisionen nachzuberechnen, weil sie/autoit dafür schlicht zu langsam ist. Man würde nicht wieder im "Jetzt" ankommen :D

    Edit: Danke für die Info über dem Fehler mit dem '=', wobei die funktion eh nicht mehr gebraucht wird

  • Moin,

    hab jetzt auch mal kurz was zusammengeschustert.
    Im Prinzip müsste man (unter Berücksichtigung der Gravitation) für jedes Objekt eine/mehrere Funktionen 2ten grades aufstellen und (im übertragenen Sinn) die Graphen der funktionen (Gleichsetzen) auf Kollision prüfen. Anschließend wird der Zeitpunkt Tx (wir beginnen jeden Frame bei T0. Jeder Zeitpunkt Tx liegt zwischen T0 und T1) der ersten Kollision ermittelt und bis dahin gerechnet. Nachdem alle Vektoren neu berechnet sind gehts zu Ty, usw usw. Bis keine Kollision mehr stattfindet und T1 erreicht ist.

    Das muss man prinzipiell so machen, sollte es wirklich genau sein.
    Aber Feste Regeln/Frame reichen aus um bei gleichen Einstellungen Gleiche Ergebnisse zu liefern. Dazu muss nicht immer alles genau stimmen.
    Um die Ungenauigkeiten etwas kleinzumachen habe ich mir überlegt die Engine intern mehr Zyklen leisten zu lassen als sie anzeigt. (beseitigt effektiv das Ruckeln durch Gravitation).
    (Bis zu einer gewissen Anzahl Zyklen ist der Rechenaufwand geringer als er wäre, würde man das ganze über Funktionsgleichungen lösen)

    Das ganze ist so aufgebaut, dass man das $OBJ problemlos durch eine Struct ersetzen kann. Auf die Mathematik lässt man dann Basic los und schon rollen 500 Kugeln statt 15.
    Die Genauigkeit mit der gearbeitet wird ist in $nStep (0<x>=1) festgelegt. Es empfehlen sich aber Zahlen die 1 so teilen können, dass eine ganze Anzahl Zyklen resultiert. (z.B. 0.25 = 4 Zyklen)

    Spoiler anzeigen
    [autoit]


    #include <GDIPlus.au3>
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt('GUIOnEventMode', 1)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    Const $iFaktor = 40
    Const $nFPS = 60
    Const $iAnzahl = 15 ; Anzahl Kugeln
    Const $iUnruhe = 2 ; Unruhe zu Beginn
    Const $nGravi = 9.81 * 1 ; Gravitation
    Const $nVerlust_Aufprall = 1 ; Verluste durch Aufprallen
    Const $nVerlust_Reibung = 1 ; Verluste durch Reibung
    Const $nStep = 0.5 ; 1/x Schritte je Frame. (mehr Rechenleistung, aber bessere Kollisionserkennung)

    [/autoit] [autoit][/autoit] [autoit]

    Const $iW = 16 * $iFaktor, $iH = 10 * $iFaktor, $iD = 356 ^ 0.5 * $iFaktor

    [/autoit] [autoit][/autoit] [autoit]

    Global $hGUI, $hBUF, $hGFX, $hBMP, $hBRU, $hPEN, $hDLL, $nLast, $aOBJ[1], $vBUF, $hDC_BUF

    [/autoit] [autoit][/autoit] [autoit]

    $hGUI = GUICreate('Kugeln - ' & $iW & 'x' & $iH & ' - FPS: 00', $iW, $iH)

    [/autoit] [autoit][/autoit] [autoit]

    ;~ $hGFX = _GDIPlus_GraphicsCreateFromHWND($hGUI)

    [/autoit] [autoit][/autoit] [autoit]

    $hDC_GUI = _WinAPI_GetDC($hGUI)

    [/autoit] [autoit][/autoit] [autoit]

    $vBUF = _Image_Create($iW, $iH)
    $hDC_BUF = DllStructGetData($vBUF, 1, 1)
    $hBUF = _GDIPlus_GraphicsCreateFromHDC($hDC_BUF)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;~ $hBMP = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGFX)
    ;~ $hBUF = _GDIPlus_ImageGetGraphicsContext($hBMP)

    [/autoit] [autoit][/autoit] [autoit]

    $hBRU = _GDIPlus_BrushCreateSolid(0xFF4080FF)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsSetSmoothingMode($hBUF, 4)

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 0 To $iAnzahl - 1 Step 1
    _AddObj(_Kugel())
    Next

    [/autoit] [autoit][/autoit] [autoit]

    _SpielFeld()

    [/autoit] [autoit][/autoit] [autoit]

    _AddObj(_Rect(100, 275, 55, 5))
    _AddObj(_Rect(150, 230, 5, 45))
    _AddObj(_Rect(150, 225, 150, 5))
    _AddObj(_Rect(250, 200, 100, 100))
    _AddObj(_Rect($iW-$iW/10, $iH-$iH/10, $iW/10, $iH/10))
    _AddObj(_Rect(450, 300, 100, 10))

    [/autoit] [autoit][/autoit] [autoit]

    WM_PAINT()

    [/autoit] [autoit][/autoit] [autoit]

    GUIRegisterMsg(0xF, 'WM_PAINT')
    OnAutoItExitRegister('_Freigeben')
    GUISetOnEvent(-3, '_Event')
    GUISetState(@SW_SHOW, $hGUI)

    [/autoit] [autoit][/autoit] [autoit]

    While Assign('nLast', ($nLast * 4 + FPS($nFPS)) / 5)
    _Run()
    WM_PAINT()
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _Run()

    [/autoit] [autoit][/autoit] [autoit]

    Local $iUbound = UBound($aOBJ)
    Local $OBJ, $nOver, $D2, $nBeschleunigung_Y, $RECT, $nDif, $nLen, $vNeu[2]

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $iUbound - 1 Step 1

    [/autoit] [autoit][/autoit] [autoit]

    $OBJ = $aOBJ[$i]

    [/autoit] [autoit][/autoit] [autoit]

    If Not IsArray($OBJ) Or Not $OBJ[0] Then ContinueLoop

    [/autoit] [autoit][/autoit] [autoit]

    $nBeschleunigung_Y = $nGravi / $nFPS

    [/autoit] [autoit][/autoit] [autoit]

    Switch $OBJ[0]
    Case 1 ; Kugel

    [/autoit] [autoit][/autoit] [autoit]

    For $t = 0 To 1 - $nStep Step $nStep

    [/autoit] [autoit][/autoit] [autoit]

    $D2 = $OBJ[3] / 2

    [/autoit] [autoit][/autoit] [autoit]

    $OBJ[6] += $nBeschleunigung_Y * $nStep

    [/autoit] [autoit][/autoit] [autoit]

    $OBJ[1] += $OBJ[5] * $nStep
    $OBJ[2] += $OBJ[6] * $nStep

    [/autoit] [autoit][/autoit] [autoit]

    For $iRect = 1 To $iUbound - 1 Step 1

    [/autoit] [autoit][/autoit] [autoit]

    $RECT = $aOBJ[$iRect]
    If Not IsArray($RECT) Or $RECT[0] = 1 Then ContinueLoop

    [/autoit] [autoit][/autoit] [autoit]

    ;~ Func _Kollision_Kreis_Punkt($x, $y, $d, $px, $py)
    ;~ Return (($x - $px) ^ 2 + ($y - $py) ^ 2) ^ 0.5 <= ($d / 2)
    ;~ EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ; Ecke Oben Rechts
    $px = $RECT[1] + $RECT[3]
    $py = $RECT[2]
    $nDif = (($OBJ[1] - $px) ^ 2 + ($OBJ[2] - $py) ^ 2) ^ 0.5
    If $nDif <= $D2 Then
    $nDif = (($D2 - $nDif) ^ 2 / 2) ^ 0.5
    $OBJ[1] += $nDif
    $OBJ[2] -= $nDif
    $nLen = (($OBJ[5] ^ 2 + $OBJ[6] ^ 2) / 2) ^ 0.5
    $vNeu[0] = ($nLen ^ 2 / 2) ^ 0.5 * 2 ^ 0.5
    $vNeu[1] = -$vNeu[0]
    $OBJ[5] = $OBJ[5] + $vNeu[0]
    $OBJ[6] = $OBJ[6] + $vNeu[1]
    $nDif = (($OBJ[5] ^ 2 + $OBJ[6] ^ 2) / 2) ^ 0.5
    $OBJ[5] *= $nLen / $nDif
    $OBJ[6] *= $nLen / $nDif
    ContinueLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Ecke Unten Rechts
    $px = $RECT[1] + $RECT[3]
    $py = $RECT[2] + $RECT[4]
    $nDif = (($OBJ[1] - $px) ^ 2 + ($OBJ[2] - $py) ^ 2) ^ 0.5
    If $nDif <= $D2 Then
    $nDif = (($D2 - $nDif) ^ 2 / 2) ^ 0.5
    $OBJ[1] += $nDif
    $OBJ[2] += $nDif
    $nLen = (($OBJ[5] ^ 2 + $OBJ[6] ^ 2) / 2) ^ 0.5
    $vNeu[0] = ($nLen ^ 2 / 2) ^ 0.5 * 2 ^ 0.5
    $vNeu[1] = $vNeu[0]
    $OBJ[5] = $OBJ[5] + $vNeu[0]
    $OBJ[6] = $OBJ[6] + $vNeu[1]
    $nDif = (($OBJ[5] ^ 2 + $OBJ[6] ^ 2) / 2) ^ 0.5
    $OBJ[5] *= $nLen / $nDif
    $OBJ[6] *= $nLen / $nDif
    ContinueLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Ecke Unten Links
    $px = $RECT[1]
    $py = $RECT[2] + $RECT[4]
    $nDif = (($OBJ[1] - $px) ^ 2 + ($OBJ[2] - $py) ^ 2) ^ 0.5
    If $nDif <= $D2 Then
    $nDif = (($D2 - $nDif) ^ 2 / 2) ^ 0.5
    $OBJ[1] -= $nDif
    $OBJ[2] += $nDif
    $nLen = (($OBJ[5] ^ 2 + $OBJ[6] ^ 2) / 2) ^ 0.5
    $vNeu[1] = ($nLen ^ 2 / 2) ^ 0.5 * 2 ^ 0.5
    $vNeu[0] = -$vNeu[1]
    $OBJ[5] = $OBJ[5] + $vNeu[0]
    $OBJ[6] = $OBJ[6] + $vNeu[1]
    $nDif = (($OBJ[5] ^ 2 + $OBJ[6] ^ 2) / 2) ^ 0.5
    $OBJ[5] *= $nLen / $nDif
    $OBJ[6] *= $nLen / $nDif
    ContinueLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Ecke Oben Links
    $px = $RECT[1]
    $py = $RECT[2]
    $nDif = (($OBJ[1] - $px) ^ 2 + ($OBJ[2] - $py) ^ 2) ^ 0.5
    If $nDif <= $D2 Then
    $nDif = (($D2 - $nDif) ^ 2 / 2) ^ 0.5
    $OBJ[1] -= $nDif
    $OBJ[2] -= $nDif
    $nLen = (($OBJ[5] ^ 2 + $OBJ[6] ^ 2) / 2) ^ 0.5
    $vNeu[1] = -(($nLen ^ 2 / 2) ^ 0.5 * 2 ^ 0.5)
    $vNeu[0] = $vNeu[1]
    $OBJ[5] = $OBJ[5] + $vNeu[0]
    $OBJ[6] = $OBJ[6] + $vNeu[1]
    $nDif = (($OBJ[5] ^ 2 + $OBJ[6] ^ 2) / 2) ^ 0.5
    $OBJ[5] *= $nLen / $nDif
    $OBJ[6] *= $nLen / $nDif
    ContinueLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; Seite Rechts
    If $OBJ[1] - $D2 <= $RECT[1] + $RECT[3] And $OBJ[2] > $RECT[2] And $OBJ[2] < $RECT[2] + $RECT[4] And $OBJ[1] >= $RECT[1] Then
    $OBJ[1] = $RECT[1] + $RECT[1] + $RECT[3] + $RECT[3] + $D2 + $D2 - $OBJ[1]
    $OBJ[5] = -$OBJ[5] * $nVerlust_Aufprall
    $OBJ[6] *= $nVerlust_Reibung
    ContinueLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Seite Unten
    If $OBJ[2] - $D2 <= $RECT[2] + $RECT[4] And $OBJ[1] > $RECT[1] And $OBJ[1] < $RECT[1] + $RECT[3] And $OBJ[2] >= $RECT[2] Then
    $OBJ[2] = $RECT[2] + $RECT[2] + $RECT[4] + $RECT[4] + $D2 + $D2 - $OBJ[2]
    $OBJ[6] = -$OBJ[6] * $nVerlust_Aufprall
    $OBJ[5] *= $nVerlust_Reibung
    ContinueLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Seite Links
    If $OBJ[1] + $D2 >= $RECT[1] And $OBJ[2] > $RECT[2] And $OBJ[2] < $RECT[2] + $RECT[4] And $OBJ[1] <= $RECT[1] + $RECT[3] Then
    $OBJ[1] = $RECT[1] + $RECT[1] - $D2 - $D2 - $OBJ[1]
    $OBJ[5] = -$OBJ[5] * $nVerlust_Aufprall
    $OBJ[6] *= $nVerlust_Reibung
    ContinueLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Seite Oben
    If $OBJ[2] + $D2 >= $RECT[2] And $OBJ[1] > $RECT[1] And $OBJ[1] < $RECT[1] + $RECT[3] And $OBJ[2] <= $RECT[2] + $RECT[4] Then
    $OBJ[2] = $RECT[2] + $RECT[2] - $D2 - $D2 - $OBJ[2]
    $OBJ[6] = -$OBJ[6] * $nVerlust_Aufprall
    $OBJ[5] *= $nVerlust_Reibung
    ContinueLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Next

    [/autoit] [autoit][/autoit] [autoit]

    ;~ If $OBJ[1] - $D2 <= 0 Then
    ;~ $OBJ[1] = Abs($OBJ[1] - $D2) + $D2
    ;~ $OBJ[5] = -$OBJ[5] * $nVerlust_Aufprall
    ;~ $OBJ[6] *= $nVerlust_Reibung
    ;~ EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;~ If $OBJ[1] + $D2 >= $iW Then
    ;~ $OBJ[1] = $iW - Abs($OBJ[1] + $D2 - $iW) - $D2
    ;~ $OBJ[5] = -$OBJ[5] * $nVerlust_Aufprall
    ;~ $OBJ[6] *= $nVerlust_Reibung
    ;~ EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;~ If $OBJ[2] + $D2 >= $iH Then
    ;~ $OBJ[2] = $iH - Abs($OBJ[2] + $D2 - $iH) - $D2
    ;~ $OBJ[6] = -$OBJ[6] * $nVerlust_Aufprall
    ;~ $OBJ[5] *= $nVerlust_Reibung
    ;~ EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;~ If $OBJ[2] - $D2 <= 0 Then
    ;~ $OBJ[2] = Abs($OBJ[2] - $D2) + $D2
    ;~ $OBJ[6] = -$OBJ[6] * $nVerlust_Aufprall
    ;~ $OBJ[5] *= $nVerlust_Reibung
    ;~ EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Next

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsFillCircleCenterF($hBUF, $OBJ[1], $OBJ[2], $OBJ[3], $hBRU)

    [/autoit] [autoit][/autoit] [autoit]

    Case 2

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsFillRect($hBUF, $OBJ[1], $OBJ[2], $OBJ[3], $OBJ[4], $hBRU)

    [/autoit] [autoit][/autoit] [autoit]

    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    $aOBJ[$i] = $OBJ

    [/autoit] [autoit][/autoit] [autoit]

    Next

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_Run

    [/autoit] [autoit][/autoit] [autoit]

    Func _AddObj($a)
    Local $iUbound = UBound($aOBJ)
    ReDim $aOBJ[$iUbound + 1]
    $aOBJ[$iUbound] = $a
    EndFunc ;==>_AddObj

    [/autoit] [autoit][/autoit] [autoit]

    Func _Kugel()
    ; 0: Kugel = 1
    ; 1: X - Mittelpunkt
    ; 2: Y - Mittelpunkt
    ; 3: Durchmesser
    ; 4: Masse
    ; 5: vX
    ; 6: vY

    [/autoit] [autoit][/autoit] [autoit]

    Local $a[7]
    $a[0] = 1
    $a[3] = Random($iD / 50, $iD / 25)
    $a[1] = Random($a[3] / 2, $iW - $a[3] / 2)
    $a[2] = Random($a[3] / 2, $iH - $a[3] / 2)
    $a[4] = ($a[3] / 2) ^ 2 * 3.141
    $a[5] = Random(-$iUnruhe, $iUnruhe)
    $a[6] = Random(-$iUnruhe, $iUnruhe)

    [/autoit] [autoit][/autoit] [autoit]

    Return $a

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_Kugel

    [/autoit] [autoit][/autoit] [autoit]

    Func _Rect($x, $y, $b, $h)

    [/autoit] [autoit][/autoit] [autoit]

    ; 0: Rect = 2
    ; 1: X Oben Links
    ; 2: Y Oben Links
    ; 3: Breite
    ; 4: Höhe

    [/autoit] [autoit][/autoit] [autoit]

    Local $a[5]
    $a[0] = 2
    $a[1] = $x
    $a[2] = $y
    $a[3] = $b
    $a[4] = $h
    Return $a

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_Rect

    [/autoit] [autoit][/autoit] [autoit]

    Func _SpielFeld()
    _AddObj(_Rect(0, 0, $iW - 20, 20))
    _AddObj(_Rect(0, 20, 20, $iH - 20))
    _AddObj(_Rect(20, $iH - 20, $iW - 20, 20))
    _AddObj(_Rect($iW - 20, 0, 20, $iH - 20))
    EndFunc ;==>_SpielFeld

    [/autoit] [autoit][/autoit] [autoit]

    Func _Event()
    Switch @GUI_CtrlId
    Case -3
    Exit
    EndSwitch
    EndFunc ;==>_Event

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_PAINT()
    Local Static $iFPS, $iTimer = TimerInit()
    If TimerDiff($iTimer) > 1000 Then
    WinSetTitle($hGUI, '', 'Kugeln - ' & $iW & 'x' & $iH & ' - FPS: ' & $iFPS & ' - Last: ' & Round($nLast, 2) * 100 & ' %')
    $iFPS = 0
    $iTimer = TimerInit()
    EndIf
    _WinAPI_BitBlt($hDC_GUI, 0, 0, $iW, $iH, $hDC_BUF, 0, 0, 0xCC0020)
    ;~ _GDIPlus_GraphicsDrawImage($hGFX, $hBMP, 0, 0)
    _GDIPlus_GraphicsClear($hBUF, 0xFFEEEEEE)
    $iFPS += 1
    EndFunc ;==>WM_PAINT

    [/autoit] [autoit][/autoit] [autoit]

    Func _Freigeben()

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDispose($hBUF)
    ;~ _GDIPlus_BitmapDispose($hBMP)
    _GDIPlus_GraphicsDispose($hGFX)
    _GDIPlus_BrushDispose($hBRU)

    [/autoit] [autoit][/autoit] [autoit]

    _Image_Delete($vBUF)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Shutdown()

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_Freigeben

    [/autoit] [autoit][/autoit] [autoit]

    Func FPS($W)
    Local Static $_t = TimerInit(), $f
    Local $s = TimerDiff($_t), $l = (1000 / $W - $s)
    $f += $l
    If $f < 0 Then $f = 0
    If $l < 0 Then $l = 0
    Sleep(Int($f / 10) * 10)
    $f -= Int($f / 10) * 10
    $_t = TimerInit()
    Return $s / ($s + $l)
    EndFunc ;==>FPS

    [/autoit] [autoit][/autoit] [autoit]

    Func _GDIPlus_GraphicsFillCircleCenter($hGFX, $x, $y, $d, $b)
    DllCall($ghGDIPDll, 'int', 'GdipFillEllipseI', 'handle', $hGFX, 'handle', $b, 'int', $x - $d / 2, 'int', $y - $d / 2, 'int', $d, 'int', $d)
    EndFunc ;==>_GDIPlus_GraphicsFillCircleCenter

    [/autoit] [autoit][/autoit] [autoit]

    Func _GDIPlus_GraphicsFillCircleCenterF($hGFX, $x, $y, $d, $b)
    DllCall($ghGDIPDll, 'int', 'GdipFillEllipse', 'handle', $hGFX, 'handle', $b, 'float', $x - $d / 2, 'float', $y - $d / 2, 'float', $d, 'float', $d)
    EndFunc ;==>_GDIPlus_GraphicsFillCircleCenterF

    [/autoit] [autoit][/autoit] [autoit]

    Func _Image_Create($iW, $iH)
    Local $Ptr, $hDC, $hBMP, $tBMI, $aDIB, $vStruct
    $hDC = _WinAPI_CreateCompatibleDC(0)
    $tBMI = DllStructCreate($tagBITMAPINFO)
    DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI) - 4)
    DllStructSetData($tBMI, "Width", $iW)
    DllStructSetData($tBMI, "Height", -$iH)
    DllStructSetData($tBMI, "Planes", 1)
    DllStructSetData($tBMI, "BitCount", 32)
    $aDIB = DllCall('GDI32.DLL', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'uint', 0)
    $hBMP = $aDIB[0]
    $Ptr = $aDIB[4]
    _WinAPI_SelectObject($hDC, $hBMP)
    $vStruct = DllStructCreate('int[5]')
    DllStructSetData($vStruct, 1, $hDC, 1)
    DllStructSetData($vStruct, 1, $iW, 2)
    DllStructSetData($vStruct, 1, $iH, 3)
    DllStructSetData($vStruct, 1, $Ptr, 4)
    DllStructSetData($vStruct, 1, $hBMP, 5)
    Return $vStruct
    EndFunc ;==>_Image_Create

    [/autoit] [autoit][/autoit] [autoit]

    Func _Image_Delete(ByRef $vStruct)
    _WinAPI_DeleteObject(DllStructGetData($vStruct, 1, 5))
    _WinAPI_DeleteDC(DllStructGetData($vStruct, 1, 1))
    $vStruct = 0
    EndFunc ;==>_Image_Delete

    [/autoit]


    .
    .

  • Hi, cooles beispiel, ich hatte auch schon daran gedacht, die kollisionen auf dieses weise zu berechnen. Diese berechung mag bei kugel zuwar funktionieren, bei den polygonen erhält man jedoch x = sin(x)/cos(x), was sich nur numerisch lösen lässt oder durch ein approximation zb. mit einem taylor polynom. Weiterhin müsste man festlegen, wie viele iterationen maximal in einer frame passieren dürfen, weil es sonst ehr langsamer als schneller wird. Als nächstes kommt eh erstmal das opengl update und andere verbesserungen und cleanup.

    Nutz jemand sonst diese engine?

    grüße Moritz

  • Hab grade noch was lustiges probiert.
    Bereiche in denen die Gravitation wirkt. (mit beliebigem Vektor).
    Frisst natürlich auch schön CPU^^

    Spoiler anzeigen
    [autoit]


    #include <GDIPlus.au3>
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt('GUIOnEventMode', 1)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    Const $iFaktor = 40
    Const $nFPS = 30
    Const $iAnzahl = 12 ; Anzahl Kugeln
    Const $iUnruhe = 6 ; Unruhe zu Beginn
    ;~ Const $nGravi = 9.81 ; Gravitation
    Const $nVerlust_Aufprall = 1 ; Verluste durch Aufprallen
    Const $nVerlust_Reibung = 1 ; Verluste durch Reibung
    Const $nStep = 0.25 ; 1/x Schritte je Frame. (mehr Rechenleistung, aber bessere Kollisionserkennung)

    [/autoit] [autoit][/autoit] [autoit]

    Const $iW = 16 * $iFaktor, $iH = 10 * $iFaktor, $iD = 356 ^ 0.5 * $iFaktor

    [/autoit] [autoit][/autoit] [autoit]

    Global $hGUI, $hBUF, $hGFX, $hBMP, $hBRU, $hPEN, $hDLL, $nLast, $aOBJ[1], $vBUF, $hDC_BUF

    [/autoit] [autoit][/autoit] [autoit]

    Global $hBRU_Grav = _GDIPlus_BrushCreateSolid(0x40FF8040)

    [/autoit] [autoit][/autoit] [autoit]

    $hGUI = GUICreate('Kugeln - ' & $iW & 'x' & $iH & ' - FPS: 00', $iW, $iH)

    [/autoit] [autoit][/autoit] [autoit]

    ;~ $hGFX = _GDIPlus_GraphicsCreateFromHWND($hGUI)

    [/autoit] [autoit][/autoit] [autoit]

    $hDC_GUI = _WinAPI_GetDC($hGUI)

    [/autoit] [autoit][/autoit] [autoit]

    $vBUF = _Image_Create($iW, $iH)
    $hDC_BUF = DllStructGetData($vBUF, 1, 1)
    $hBUF = _GDIPlus_GraphicsCreateFromHDC($hDC_BUF)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;~ $hBMP = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGFX)
    ;~ $hBUF = _GDIPlus_ImageGetGraphicsContext($hBMP)

    [/autoit] [autoit][/autoit] [autoit]

    $hBRU = _GDIPlus_BrushCreateSolid(0xFF4080FF)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsSetSmoothingMode($hBUF, 4)

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 0 To $iAnzahl - 1 Step 1
    _AddObj(_Kugel())
    Next

    [/autoit] [autoit][/autoit] [autoit]

    _SpielFeld()

    [/autoit] [autoit][/autoit] [autoit]

    _AddObj(_Rect(100, 275, 55, 5))
    _AddObj(_Rect(150, 230, 5, 45))
    _AddObj(_Rect(150, 225, 150, 5))
    _AddObj(_Rect(250, 200, 100, 100))

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    _AddObj(_Rect($iW - $iW / 10, $iH - $iH / 10, $iW / 10, $iH / 10))
    _AddObj(_Rect(450, 300, 100, 10))

    [/autoit] [autoit][/autoit] [autoit]

    ;~ _AddObj(_Gravitation_Rect($iW/4, $iH/4, $iW/2, $iH/2, 0, 0.5))

    [/autoit] [autoit][/autoit] [autoit]

    _AddObj(_Rect(450, 275, 170, 5))
    _AddObj(_Rect(450, 190, 5, 85))
    _AddObj(_Gravitation_Rect(455, 190, 165, 85, 0, -0.3))

    [/autoit] [autoit][/autoit] [autoit]

    _AddObj(_Rect(185, 20, 5, 85))
    _AddObj(_Gravitation_Rect(20, 20, 165, 85, 0, 0.3))

    [/autoit] [autoit][/autoit] [autoit]

    _AddObj(_Gravitation_Rect(155, 230, 95, 50, 0, 0.3))

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;~ _AddObj(_Gravitation_Rect($iW/3, 0, $iW/6, $iH, 0.3, 0))
    ;~ _AddObj(_Gravitation_Rect($iW/3+$iW/6, 0, $iW/6, $iH, -0.3, 0))

    [/autoit] [autoit][/autoit] [autoit]

    WM_PAINT()

    [/autoit] [autoit][/autoit] [autoit]

    GUIRegisterMsg(0xF, 'WM_PAINT')
    OnAutoItExitRegister('_Freigeben')
    GUISetOnEvent(-3, '_Event')
    GUISetState(@SW_SHOW, $hGUI)

    [/autoit] [autoit][/autoit] [autoit]

    While Assign('nLast', ($nLast * 4 + FPS($nFPS)) / 5)
    _Run()
    WM_PAINT()
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _Run()

    [/autoit] [autoit][/autoit] [autoit]

    Local $iUbound = UBound($aOBJ)
    Local $OBJ, $nOver, $D2, $RECT, $nDif, $nLen, $vNeu[2], $GRAV

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $iUbound - 1 Step 1

    [/autoit] [autoit][/autoit] [autoit]

    $OBJ = $aOBJ[$i]

    [/autoit] [autoit][/autoit] [autoit]

    If Not IsArray($OBJ) Or Not $OBJ[0] Then ContinueLoop
    Switch $OBJ[0]
    Case 1 ; Kugel

    [/autoit] [autoit][/autoit] [autoit]

    $D2 = $OBJ[3] / 2

    [/autoit] [autoit][/autoit] [autoit]

    For $t = 0 To 1 - $nStep Step $nStep

    [/autoit] [autoit][/autoit] [autoit]

    $OBJ[7] = 0
    $OBJ[8] = 0

    [/autoit] [autoit][/autoit] [autoit]

    For $g = 1 To $iUbound - 1 Step 1

    [/autoit] [autoit][/autoit] [autoit]

    $GRAV = $aOBJ[$g]
    If Not IsArray($GRAV) Or Not ($GRAV[0] = 3) Then ContinueLoop

    [/autoit] [autoit][/autoit] [autoit]

    If $OBJ[1] > $GRAV[1] And $OBJ[2] > $GRAV[2] And $OBJ[1] < $GRAV[1] + $GRAV[3] And $OBJ[2] < $GRAV[2] + $GRAV[4] Then
    $OBJ[7] += $GRAV[5]
    $OBJ[8] += $GRAV[6]
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Next

    [/autoit] [autoit][/autoit] [autoit]

    $OBJ[5] += $OBJ[7] * $nStep
    $OBJ[6] += $OBJ[8] * $nStep

    [/autoit] [autoit][/autoit] [autoit]

    $OBJ[1] += $OBJ[5] * $nStep
    $OBJ[2] += $OBJ[6] * $nStep

    [/autoit] [autoit][/autoit] [autoit]

    For $iRect = 1 To $iUbound - 1 Step 1

    [/autoit] [autoit][/autoit] [autoit]

    $RECT = $aOBJ[$iRect]
    If Not IsArray($RECT) Or Not ($RECT[0] = 2) Then ContinueLoop

    [/autoit] [autoit][/autoit] [autoit]

    ; Seite Rechts
    If $OBJ[1] - $D2 <= $RECT[1] + $RECT[3] And $OBJ[2] > $RECT[2] And $OBJ[2] < $RECT[2] + $RECT[4] And $OBJ[1] >= $RECT[1] Then
    $OBJ[1] = $RECT[1] + $RECT[1] + $RECT[3] + $RECT[3] + $D2 + $D2 - $OBJ[1]
    $OBJ[5] = -$OBJ[5] * $nVerlust_Aufprall
    $OBJ[6] *= $nVerlust_Reibung
    ContinueLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Seite Unten
    If $OBJ[2] - $D2 <= $RECT[2] + $RECT[4] And $OBJ[1] > $RECT[1] And $OBJ[1] < $RECT[1] + $RECT[3] And $OBJ[2] >= $RECT[2] Then
    $OBJ[2] = $RECT[2] + $RECT[2] + $RECT[4] + $RECT[4] + $D2 + $D2 - $OBJ[2]
    $OBJ[6] = -$OBJ[6] * $nVerlust_Aufprall
    $OBJ[5] *= $nVerlust_Reibung
    ContinueLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Seite Links
    If $OBJ[1] + $D2 >= $RECT[1] And $OBJ[2] > $RECT[2] And $OBJ[2] < $RECT[2] + $RECT[4] And $OBJ[1] <= $RECT[1] + $RECT[3] Then
    $OBJ[1] = $RECT[1] + $RECT[1] - $D2 - $D2 - $OBJ[1]
    $OBJ[5] = -$OBJ[5] * $nVerlust_Aufprall
    $OBJ[6] *= $nVerlust_Reibung
    ContinueLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Seite Oben
    If $OBJ[2] + $D2 >= $RECT[2] And $OBJ[1] > $RECT[1] And $OBJ[1] < $RECT[1] + $RECT[3] And $OBJ[2] <= $RECT[2] + $RECT[4] Then
    $OBJ[2] = $RECT[2] + $RECT[2] - $D2 - $D2 - $OBJ[2]
    $OBJ[6] = -$OBJ[6] * $nVerlust_Aufprall
    $OBJ[5] *= $nVerlust_Reibung
    ContinueLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Ecke Oben Rechts
    $px = $RECT[1] + $RECT[3]
    $py = $RECT[2]
    $nDif = (($OBJ[1] - $px) ^ 2 + ($OBJ[2] - $py) ^ 2) ^ 0.5
    If $nDif <= $D2 Then
    $nDif = (($D2 - $nDif) ^ 2 / 2) ^ 0.5
    $OBJ[1] += $nDif
    $OBJ[2] -= $nDif
    $nLen = (($OBJ[5] ^ 2 + $OBJ[6] ^ 2) / 2) ^ 0.5
    $vNeu[0] = ($nLen ^ 2 / 2) ^ 0.5 * 2 ^ 0.5
    $vNeu[1] = -$vNeu[0]
    $OBJ[5] = $OBJ[5] + $vNeu[0]
    $OBJ[6] = $OBJ[6] + $vNeu[1]
    $nDif = (($OBJ[5] ^ 2 + $OBJ[6] ^ 2) / 2) ^ 0.5
    $OBJ[5] *= $nLen / $nDif
    $OBJ[6] *= $nLen / $nDif
    ContinueLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Ecke Unten Rechts
    $px = $RECT[1] + $RECT[3]
    $py = $RECT[2] + $RECT[4]
    $nDif = (($OBJ[1] - $px) ^ 2 + ($OBJ[2] - $py) ^ 2) ^ 0.5
    If $nDif <= $D2 Then
    $nDif = (($D2 - $nDif) ^ 2 / 2) ^ 0.5
    $OBJ[1] += $nDif
    $OBJ[2] += $nDif
    $nLen = (($OBJ[5] ^ 2 + $OBJ[6] ^ 2) / 2) ^ 0.5
    $vNeu[0] = ($nLen ^ 2 / 2) ^ 0.5 * 2 ^ 0.5
    $vNeu[1] = $vNeu[0]
    $OBJ[5] = $OBJ[5] + $vNeu[0]
    $OBJ[6] = $OBJ[6] + $vNeu[1]
    $nDif = (($OBJ[5] ^ 2 + $OBJ[6] ^ 2) / 2) ^ 0.5
    $OBJ[5] *= $nLen / $nDif
    $OBJ[6] *= $nLen / $nDif
    ContinueLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Ecke Unten Links
    $px = $RECT[1]
    $py = $RECT[2] + $RECT[4]
    $nDif = (($OBJ[1] - $px) ^ 2 + ($OBJ[2] - $py) ^ 2) ^ 0.5
    If $nDif <= $D2 Then
    $nDif = (($D2 - $nDif) ^ 2 / 2) ^ 0.5
    $OBJ[1] -= $nDif
    $OBJ[2] += $nDif
    $nLen = (($OBJ[5] ^ 2 + $OBJ[6] ^ 2) / 2) ^ 0.5
    $vNeu[1] = ($nLen ^ 2 / 2) ^ 0.5 * 2 ^ 0.5
    $vNeu[0] = -$vNeu[1]
    $OBJ[5] = $OBJ[5] + $vNeu[0]
    $OBJ[6] = $OBJ[6] + $vNeu[1]
    $nDif = (($OBJ[5] ^ 2 + $OBJ[6] ^ 2) / 2) ^ 0.5
    $OBJ[5] *= $nLen / $nDif
    $OBJ[6] *= $nLen / $nDif
    ContinueLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Ecke Oben Links
    $px = $RECT[1]
    $py = $RECT[2]
    $nDif = (($OBJ[1] - $px) ^ 2 + ($OBJ[2] - $py) ^ 2) ^ 0.5
    If $nDif <= $D2 Then
    $nDif = (($D2 - $nDif) ^ 2 / 2) ^ 0.5
    $OBJ[1] -= $nDif
    $OBJ[2] -= $nDif
    $nLen = (($OBJ[5] ^ 2 + $OBJ[6] ^ 2) / 2) ^ 0.5
    $vNeu[1] = -(($nLen ^ 2 / 2) ^ 0.5 * 2 ^ 0.5)
    $vNeu[0] = $vNeu[1]
    $OBJ[5] = $OBJ[5] + $vNeu[0]
    $OBJ[6] = $OBJ[6] + $vNeu[1]
    $nDif = (($OBJ[5] ^ 2 + $OBJ[6] ^ 2) / 2) ^ 0.5
    $OBJ[5] *= $nLen / $nDif
    $OBJ[6] *= $nLen / $nDif
    ContinueLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Next

    [/autoit] [autoit][/autoit] [autoit]

    ;~ If $OBJ[1] - $D2 <= 0 Then
    ;~ $OBJ[1] = Abs($OBJ[1] - $D2) + $D2
    ;~ $OBJ[5] = -$OBJ[5] * $nVerlust_Aufprall
    ;~ $OBJ[6] *= $nVerlust_Reibung
    ;~ EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;~ If $OBJ[1] + $D2 >= $iW Then
    ;~ $OBJ[1] = $iW - Abs($OBJ[1] + $D2 - $iW) - $D2
    ;~ $OBJ[5] = -$OBJ[5] * $nVerlust_Aufprall
    ;~ $OBJ[6] *= $nVerlust_Reibung
    ;~ EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;~ If $OBJ[2] + $D2 >= $iH Then
    ;~ $OBJ[2] = $iH - Abs($OBJ[2] + $D2 - $iH) - $D2
    ;~ $OBJ[6] = -$OBJ[6] * $nVerlust_Aufprall
    ;~ $OBJ[5] *= $nVerlust_Reibung
    ;~ EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;~ If $OBJ[2] - $D2 <= 0 Then
    ;~ $OBJ[2] = Abs($OBJ[2] - $D2) + $D2
    ;~ $OBJ[6] = -$OBJ[6] * $nVerlust_Aufprall
    ;~ $OBJ[5] *= $nVerlust_Reibung
    ;~ EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Next

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsFillCircleCenterF($hBUF, $OBJ[1], $OBJ[2], $OBJ[3], $hBRU)

    [/autoit] [autoit][/autoit] [autoit]

    Case 2

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsFillRect($hBUF, $OBJ[1], $OBJ[2], $OBJ[3], $OBJ[4], $hBRU)

    [/autoit] [autoit][/autoit] [autoit]

    Case 3
    _GDIPlus_GraphicsFillRect($hBUF, $OBJ[1], $OBJ[2], $OBJ[3], $OBJ[4], $hBRU_Grav)

    [/autoit] [autoit][/autoit] [autoit]

    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    $aOBJ[$i] = $OBJ

    [/autoit] [autoit][/autoit] [autoit]

    Next

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_Run

    [/autoit] [autoit][/autoit] [autoit]

    Func _AddObj($a)
    Local $iUbound = UBound($aOBJ)
    ReDim $aOBJ[$iUbound + 1]
    $aOBJ[$iUbound] = $a
    EndFunc ;==>_AddObj

    [/autoit] [autoit][/autoit] [autoit]

    Func _Kugel()
    ; 0: Kugel = 1
    ; 1: X - Mittelpunkt
    ; 2: Y - Mittelpunkt
    ; 3: Durchmesser
    ; 4: Masse
    ; 5: vX
    ; 6: vY
    ; 7: aX
    ; 8: aY

    [/autoit] [autoit][/autoit] [autoit]

    Local $a[9]
    $a[0] = 1
    $a[3] = Random($iD / 50, $iD / 25)
    $a[1] = Random($a[3] / 2, $iW - $a[3] / 2)
    $a[2] = Random($a[3] / 2, $iH - $a[3] / 2)
    $a[4] = ($a[3] / 2) ^ 2 * 3.141
    $a[5] = Random(-$iUnruhe, $iUnruhe)
    $a[6] = Random(-$iUnruhe, $iUnruhe)
    $a[7] = 0
    $a[8] = 0

    [/autoit] [autoit][/autoit] [autoit]

    Return $a

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_Kugel

    [/autoit] [autoit][/autoit] [autoit]

    Func _Rect($x, $y, $b, $h)

    [/autoit] [autoit][/autoit] [autoit]

    ; 0: Rect = 2
    ; 1: X Oben Links
    ; 2: Y Oben Links
    ; 3: Breite
    ; 4: Höhe

    [/autoit] [autoit][/autoit] [autoit]

    Local $a[5]
    $a[0] = 2
    $a[1] = $x
    $a[2] = $y
    $a[3] = $b
    $a[4] = $h
    Return $a

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_Rect

    [/autoit] [autoit][/autoit] [autoit]

    Func _Gravitation_Rect($x, $y, $b, $h, $ax = 0, $ay = 9.81)

    [/autoit] [autoit][/autoit] [autoit]

    ; 0: Gravitation_Rect = 3
    ; 1: X
    ; 2: Y
    ; 3: B
    ; 4: H
    ; 5: ax - Beschleunigung in X Richtung
    ; 6: ay - Beschleunigung in Y Richtung

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Local $a[7]
    $a[0] = 3
    $a[1] = $x
    $a[2] = $y
    $a[3] = $b
    $a[4] = $h
    $a[5] = $ax
    $a[6] = $ay
    Return $a

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_Gravitation_Rect

    [/autoit] [autoit][/autoit] [autoit]

    Func _SpielFeld()
    _AddObj(_Rect(0, 0, $iW - 20, 20))
    _AddObj(_Rect(0, 20, 20, $iH - 20))
    _AddObj(_Rect(20, $iH - 20, $iW - 20, 20))
    _AddObj(_Rect($iW - 20, 0, 20, $iH - 20))
    EndFunc ;==>_SpielFeld

    [/autoit] [autoit][/autoit] [autoit]

    Func _Event()
    Switch @GUI_CtrlId
    Case -3
    Exit
    EndSwitch
    EndFunc ;==>_Event

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_PAINT()
    Local Static $iFPS, $iTimer = TimerInit()
    If TimerDiff($iTimer) > 1000 Then
    WinSetTitle($hGUI, '', 'Kugeln - ' & $iW & 'x' & $iH & ' - FPS: ' & $iFPS & ' - Last: ' & Round($nLast, 2) * 100 & ' %')
    $iFPS = 0
    $iTimer = TimerInit()
    EndIf
    _WinAPI_BitBlt($hDC_GUI, 0, 0, $iW, $iH, $hDC_BUF, 0, 0, 0xCC0020)
    ;~ _GDIPlus_GraphicsDrawImage($hGFX, $hBMP, 0, 0)
    _GDIPlus_GraphicsClear($hBUF, 0xFFEEEEEE)
    $iFPS += 1
    EndFunc ;==>WM_PAINT

    [/autoit] [autoit][/autoit] [autoit]

    Func _Freigeben()

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDispose($hBUF)
    ;~ _GDIPlus_BitmapDispose($hBMP)
    _GDIPlus_GraphicsDispose($hGFX)
    _GDIPlus_BrushDispose($hBRU)

    [/autoit] [autoit][/autoit] [autoit]

    _WinAPI_ReleaseDC($hGUI, $hDC_GUI)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_BrushDispose($hBRU_Grav)

    [/autoit] [autoit][/autoit] [autoit]

    _Image_Delete($vBUF)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Shutdown()

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_Freigeben

    [/autoit] [autoit][/autoit] [autoit]

    Func FPS($W)
    Local Static $_t = TimerInit(), $f
    Local $s = TimerDiff($_t), $l = (1000 / $W - $s)
    $f += $l
    If $f < 0 Then $f = 0
    If $l < 0 Then $l = 0
    Sleep(Int($f / 10) * 10)
    $f -= Int($f / 10) * 10
    $_t = TimerInit()
    Return $s / ($s + $l)
    EndFunc ;==>FPS

    [/autoit] [autoit][/autoit] [autoit]

    Func _GDIPlus_GraphicsFillCircleCenter($hGFX, $x, $y, $d, $b)
    DllCall($ghGDIPDll, 'int', 'GdipFillEllipseI', 'handle', $hGFX, 'handle', $b, 'int', $x - $d / 2, 'int', $y - $d / 2, 'int', $d, 'int', $d)
    EndFunc ;==>_GDIPlus_GraphicsFillCircleCenter

    [/autoit] [autoit][/autoit] [autoit]

    Func _GDIPlus_GraphicsFillCircleCenterF($hGFX, $x, $y, $d, $b)
    DllCall($ghGDIPDll, 'int', 'GdipFillEllipse', 'handle', $hGFX, 'handle', $b, 'float', $x - $d / 2, 'float', $y - $d / 2, 'float', $d, 'float', $d)
    EndFunc ;==>_GDIPlus_GraphicsFillCircleCenterF

    [/autoit] [autoit][/autoit] [autoit]

    Func _Image_Create($iW, $iH)
    Local $Ptr, $hDC, $hBMP, $tBMI, $aDIB, $vStruct
    $hDC = _WinAPI_CreateCompatibleDC(0)
    $tBMI = DllStructCreate($tagBITMAPINFO)
    DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI) - 4)
    DllStructSetData($tBMI, "Width", $iW)
    DllStructSetData($tBMI, "Height", -$iH)
    DllStructSetData($tBMI, "Planes", 1)
    DllStructSetData($tBMI, "BitCount", 32)
    $aDIB = DllCall('GDI32.DLL', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'uint', 0)
    $hBMP = $aDIB[0]
    $Ptr = $aDIB[4]
    _WinAPI_SelectObject($hDC, $hBMP)
    $vStruct = DllStructCreate('int[5]')
    DllStructSetData($vStruct, 1, $hDC, 1)
    DllStructSetData($vStruct, 1, $iW, 2)
    DllStructSetData($vStruct, 1, $iH, 3)
    DllStructSetData($vStruct, 1, $Ptr, 4)
    DllStructSetData($vStruct, 1, $hBMP, 5)
    Return $vStruct
    EndFunc ;==>_Image_Create

    [/autoit] [autoit][/autoit] [autoit]

    Func _Image_Delete(ByRef $vStruct)
    _WinAPI_DeleteObject(DllStructGetData($vStruct, 1, 5))
    _WinAPI_DeleteDC(DllStructGetData($vStruct, 1, 1))
    $vStruct = 0
    EndFunc ;==>_Image_Delete

    [/autoit]


    .
    .

  • Freut mich ungemein das du deine Engine wieder in Angriff genommen hast
    Diese Engine bietet ein riesen Potential

    Werd es mir bei genügend Zeit mal genau zur Gemüte führen


    /Ot :
    AutoIt.de hat keinen Thx-Buttons?

  • Hm. Also die letzte Version hat meiner Meinung nach Welten besser funktioniert. Hier fällt mir auf:

    • Objekte rutschen wild hin und her
    • Objekte springen ohne Grund wild durch den Raum, manchmal aber dann völlig ohne Grund
    • Objekte rutschen ineinander, kollidieren tun sie auch viel zu spät, sie überlappen sich fast immer
    • Schnelle Objekte verlassen einfach so den Raum, also durch die Wände. Wenn sich ein Objekt draußen befindet, stehen alle anderen (endlich :D ) still, und lassen sich nicht bewegen
    • Auf Objekte gezeichnete Fadenkreuze bleiben dort gezeichnet, bis sich das Objekt bewegt
    • Im Skript fehlt eine Swap-Funktion, die EXE hat eine unerhörte Breite ;)

    Denke das wird noch :D

  • Version 3 war halt komplett neu geschrieben, und enthält daher noch nen paar bugs, aber ich kann dir sagen, dass diese Version um Welten besser ist ;). Und du kannst die objekte nicht mehr bewegen weil sie "schlafen", wenn du 'w' wie wake drückst, dann gehts wieder

  • Update PhysicEngine Version 3.1

    Bessere
    Kollisionserkennung, andere Kollisionsverarbeitung,
    Geschwindigkeitssteigerung, bessere Oberfläche, bessere
    Kollisionshierarchie, Reibung, Fehler behoben

  • Ich kann das script leider nicht starten..

    PhysicEngine_3_Opengl.au3(297,14) : WARNING: $hBitmap: possibly used before declaration.
    PhysicEngine_3_Polygon.au3(627,141) : ERROR: phys_PolgonGetFarestPointInDirection() called with wrong number of args.
    PhysicEngine_3_Polygon.au3(594,189) : REF: definition of phys_PolgonGetFarestPointInDirection().

    Ich habe AutoIt version 3.3.8.1

  • Jetzt sind es noch mehr:

    Spoiler anzeigen


    PhysicEngine_3_Opengl.au3(297,14) : WARNING: $hBitmap: possibly used before declaration.
    If $hBitmap =
    ~~~~~~~~~~~~^
    PhysicEngine_3_Draw.au3(89,24) : WARNING: $PHYS_DRAW_MODE: possibly used before declaration.
    Switch $PHYS_DRAW_MODE
    ~~~~~~~~~~~~~~~~~~~~~~^
    PhysicEngine_3_Draw.au3(90,20) : WARNING: $RENDER_NULL: possibly used before declaration.
    Case $RENDER_NULL
    ~~~~~~~~~~~~~~~~~^
    PhysicEngine_3_Draw.au3(91,23) : WARNING: $RENDER_GDIPLUS: possibly used before declaration.
    Case $RENDER_GDIPLUS
    ~~~~~~~~~~~~~~~~~~~~^
    \PhysicEngine_3_Draw.au3(109,22) : WARNING: $RENDER_OPENGL: possibly used before declaration.
    Case $RENDER_OPENGL
    ~~~~~~~~~~~~~~~~~~~^
    PhysicEngine_3_Draw.au3(118,38) : WARNING: $PHYS_DRAW_SCALE: possibly used before declaration.
    glScalef(2/$width*$PHYS_DRAW_SCALE,
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
    PhysicEngine_3_Draw.au3(238,34) : WARNING: $PHYS_DRAW_COLLISION_CIRCLES: possibly used before declaration.
    If $PHYS_DRAW_COLLISION_CIRCLES Then
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
    PhysicEngine_3_Draw.au3(239,32) : WARNING: $PHYS_DRAW_COLLISION_BOXES: possibly used before declaration.
    If $PHYS_DRAW_COLLISION_BOXES Then
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
    PhysicEngine_3_Draw.au3(354,62) : WARNING: $PHYS_DRAW_CLEARCOLOR: possibly used before declaration.
    _GDIPlus_GraphicsClear($g_hBackbuffer, $PHYS_DRAW_CLEARCOLOR)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
    PhysicEngine_3_Collision.au3(76,44) : ERROR: phys_LinesIntersect() called with wrong number of args.
    $InterectionPointX, $InterectionPointY )
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
    PhysicEngine_3_Math.au3(10,155) : REF: definition of phys_LinesIntersect().
    Func phys_LinesIntersect( $line_1_start_x, $line_1_start_y, $line_1_end_x, $line_1_end_y, $line_2_start_x, $line_2_start_y, $line_2_end_x, $line_2_end_y )
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
    Physik Engine 3.1\PhysicEngine_3_Collision.au3(182,9) : ERROR: syntax error
    Local B_X
    ~~~~~~^
    PhysicEngine_3_Opengl.au3(297,14) : ERROR: $hBitmap: undeclared global variable.
    If $hBitmap =
    ~~~~~~~~~~~~^
    PhysicEngine_3_Draw.au3(89,24) : ERROR: $PHYS_DRAW_MODE: undeclared global variable.
    Switch $PHYS_DRAW_MODE
    ~~~~~~~~~~~~~~~~~~~~~~^
    PhysicEngine_3_Draw.au3(90,20) : ERROR: $RENDER_NULL: undeclared global variable.
    Case $RENDER_NULL
    ~~~~~~~~~~~~~~~~~^
    PhysicEngine_3_Draw.au3(91,23) : ERROR: $RENDER_GDIPLUS: undeclared global variable.
    Case $RENDER_GDIPLUS
    ~~~~~~~~~~~~~~~~~~~~^
    PhysicEngine_3_Draw.au3(109,22) : ERROR: $RENDER_OPENGL: undeclared global variable.
    Case $RENDER_OPENGL
    ~~~~~~~~~~~~~~~~~~~^
    PhysicEngine_3_Draw.au3(118,38) : ERROR: $PHYS_DRAW_SCALE: undeclared global variable.
    glScalef(2/$width*$PHYS_DRAW_SCALE,
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
    PhysicEngine_3_Draw.au3(238,34) : ERROR: $PHYS_DRAW_COLLISION_CIRCLES: undeclared global variable.
    If $PHYS_DRAW_COLLISION_CIRCLES Then
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
    PhysicEngine_3_Draw.au3(239,32) : ERROR: $PHYS_DRAW_COLLISION_BOXES: undeclared global variable.
    If $PHYS_DRAW_COLLISION_BOXES Then
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
    PhysicEngine_3_Draw.au3(354,62) : ERROR: $PHYS_DRAW_CLEARCOLOR: undeclared global variable.
    _GDIPlus_GraphicsClear($g_hBackbuffer, $PHYS_DRAW_CLEARCOLOR)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
    PhysicEngine_3_Collision.au3(46,68) : ERROR: phys_CollisionBoxesIntersect(): undefined function.
    If Not phys_CollisionBoxesIntersect( $polygon_id_1, $polygon_id_2 )


    Mit einem Klick auf Continue scheint es aber zu funktionieren. Allerdings sind die Objekte nicht mehr mit der Maus beeinflussbar..
    Die Compilierte Version zeichnet nichteinmal irgendwas. Es erscheint einfach nur eine leere Gui. Auf Xp/7 getested..

  • Also, die kompilete Version musste vllt zwei drei mal starten, weiß auch nicht wieso, und wenn du objekte beeinflussen willst musste erstmal in der settings.ini "debug=1" machen. dann kannste objekte mit der rechten maustaste selektieren und dann mit der linken kraft ausüben und wenn die objekte schlafen einfach mit "w" wie wake aufwecken.