Moin,
Es gibt ja schon einige Partikelexplosionen hier im Forum.
Die habe ich mir auch alle schon brav angesehen und habe feststellen müssen, dass alle mangelhaft sind^^
Fast alle nutzen ein Rechteck als Partikelgrenze (Kommt von der 2Dimensionalen Berechnung ohne Sinus oder Vektorbeträge)
Ich möchte eine Partikelexplosion in (pseudo) 3D haben. (Es ginge auch echtes 3D. Da weiß ich aber nicht wie das richtig funktioniert. Dazu muss man lineare Gleichungssysteme lösen oder so^^)
-> Partikel haben x, y und z Koord und Geschwindigkeit
-> usw usw.
Das Problem ist: Ich bekomme es nicht hin, dass es so aussieht als würden die Partikel tatsächlich "nach hinten" fliegen...
Voluminös sieht die Explosion schon aus. Man sieht aber immer nur eine "Halbkugel" als Begrenzung.
Die Anzahl Partikel habe ich mal auf 200 gestellt, damit man schön alles sieht.
In Zeile 127/128 kann man sich die nach vorne bewegenden Partikel oder die, die sich nach hinten bewegen anzeigen lassen.
Dann erkennt man, dass die, die nach hinten gehen auch kleiner werden, die nach vorne größer usw.
Ich bekomm die Perspektive aber nicht gebacken^^
PS: Man kann eine lustige optische Täuschung sehen, wenn man so ca. 10 Explosionen anschaut. Anschließend klickt man während einer Explosion auf die Titelleiste um das Bild einzufrieren. Jetzt sieht es so aus als würde sich das bild zusammenziehen^^
Spoiler anzeigen
#include <GDIPlus.au3>
#include <Misc.au3>
Opt('GUICloseOnESC', 0)
Opt('GUIOnEventMode', 1)
Opt('MustDeclareVars', 1)
Opt('MouseCoordMode', 2)
Global Const $iB = 400, $iH = 400
Global $hGFX, $hBMP, $hBUF, $hGUI, $Partikel[1][10], $hBrush[256], $L_Klick, $L_Tmp, $mPos[2]
OnAutoItExitRegister('_Release')
[/autoit] [autoit][/autoit] [autoit]_Main()
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]Func _Main()
[/autoit] [autoit][/autoit] [autoit]$hGUI = GUICreate('Explosion', $iB, $iH)
WinSetTrans($hGUI, '', 255)
GUISetBkColor(0xFF0000, $hGUI)
GUISetOnEvent(-3, '_Exit', $hGUI)
_GDIPlus_Startup()
[/autoit] [autoit][/autoit] [autoit]$hGFX = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBMP = _GDIPlus_BitmapCreateFromGraphics($iB, $iH, $hGFX)
$hBUF = _GDIPlus_ImageGetGraphicsContext($hBMP)
$hBrush = __GDIPlus_BrushCreateSolid('FF6800')
[/autoit] [autoit][/autoit] [autoit]_GDIPlus_GraphicsSetSmoothingMode($hBUF, 4)
[/autoit] [autoit][/autoit] [autoit]GUIRegisterMsg(0xF, 'WM_PAINT')
[/autoit] [autoit][/autoit] [autoit]GUISetState(@SW_SHOW, $hGUI)
[/autoit] [autoit][/autoit] [autoit]_AddExplosion($iB / 2, $iH / 2)
[/autoit] [autoit][/autoit] [autoit]While Sleep(20)
$mPos = MouseGetPos()
$L_Tmp = _IsPressed('01')
If $L_Klick And Not $L_Tmp Then _AddExplosion($mPos[0], $mPos[1])
$L_Klick = $L_Tmp
_GDIPlus_GraphicsClear($hBUF, 0x40000000)
_DrawPartikel()
WM_PAINT()
WEnd
EndFunc ;==>_Main
[/autoit] [autoit][/autoit] [autoit]Func _AddExplosion($x, $y, $D = 4, $n = 200)
[/autoit] [autoit][/autoit] [autoit]; Partikel
; 0 - x
; 1 - y
; 2 - z
; 3 - Vx
; 4 - Vy
; 5 - Vz
; 6 - Counter
Local $u = UBound($Partikel, 1)
ReDim $Partikel[$u + $n + 1][UBound($Partikel, 2)]
For $i = $u To $u + $n Step 1
$Partikel[$i][0] = $x
$Partikel[$i][1] = $y
$Partikel[$i][2] = 0 ; z = 0 - In der Ebene
$Partikel[$i][3] = Random(0, 1)
$Partikel[$i][4] = Random(0, (1 - $Partikel[$i][3]) ^ 0.5)
$Partikel[$i][5] = (1 - $Partikel[$i][3] ^ 2 - $Partikel[$i][4] ^ 2) ^ 0.5
$Partikel[$i][6] = 0
$Partikel[$i][7] = $D ; Durchmesser
$Partikel[$i][8] = $x
$Partikel[$i][9] = $y
$Partikel[$i][3] = _PN($Partikel[$i][3])
$Partikel[$i][4] = _PN($Partikel[$i][4])
$Partikel[$i][5] = _PN($Partikel[$i][5])
If Random(0, 1, 1) Then _Swap($Partikel[$i][3], $Partikel[$i][4])
If Random(0, 1, 1) Then _Swap($Partikel[$i][5], $Partikel[$i][4])
If Random(0, 1, 1) Then _Swap($Partikel[$i][3], $Partikel[$i][5])
Next
[/autoit] [autoit][/autoit] [autoit]EndFunc ;==>_AddExplosion
[/autoit] [autoit][/autoit] [autoit]Func _Swap(ByRef $a, ByRef $b)
Local $c = $a
$a = $b
$b = $c
EndFunc ;==>_Swap
Func _PN($a)
If Random(0, 1, 1) Then Return $a
Return -$a
EndFunc ;==>_PN
Func _DrawPartikel()
[/autoit] [autoit][/autoit] [autoit]Local $u = UBound($Partikel), $D, $K[$u], $T, $x, $y
[/autoit] [autoit][/autoit] [autoit]For $i = 1 To $u - 1 Step 1
[/autoit] [autoit][/autoit] [autoit]$D = (9 + $Partikel[$i][2] / 30)
If $D < 0 Then ContinueLoop
$T = Int(256 - ($Partikel[$i][6] / $Partikel[$i][7] * 25.5)) * 0.9 - 20 / $D
[/autoit] [autoit][/autoit] [autoit]If $T < -5 Then
ReDim $Partikel[$i][UBound($Partikel, 2)]
ExitLoop
EndIf
If $T <= 0 Then
$Partikel[$i][2] += $Partikel[$i][5] * $Partikel[$i][7]
$Partikel[$i][6] += 1
ContinueLoop
EndIf
$x = $Partikel[$i][3] * $Partikel[$i][6] * $Partikel[$i][7] + $Partikel[$i][8] - $D / 2
$y = $Partikel[$i][4] * $Partikel[$i][6] * $Partikel[$i][7] + $Partikel[$i][9] - $D / 2
If $Partikel[$i][2] < 0 Then _GDIPlus_GraphicsFillEllipse($hBUF, $x, $y, $D, $D, $hBrush[$T - 1]) ; Hintere Halbkugel - Partikel werden kleiner
;~ If $Partikel[$i][2] > 0 Then _GDIPlus_GraphicsFillEllipse($hBUF, $x, $y, $D, $D, $hBrush[$T - 1]) ; Vordere Halbkugel - Partikel werden größer
$Partikel[$i][2] += $Partikel[$i][5] * $Partikel[$i][7]
$Partikel[$i][6] += 1
Next
[/autoit] [autoit][/autoit] [autoit]EndFunc ;==>_DrawPartikel
[/autoit] [autoit][/autoit] [autoit]Func __GDIPlus_BrushCreateSolid($c)
[/autoit] [autoit][/autoit] [autoit]Local $a[256]
[/autoit] [autoit][/autoit] [autoit]For $i = 0 To 255 Step 1
$a[$i] = _GDIPlus_BrushCreateSolid('0x' & Hex($i, 2) & $c)
Next
Return $a
[/autoit] [autoit][/autoit] [autoit]EndFunc ;==>__GDIPlus_BrushCreateSolid
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]Func WM_PAINT()
_GDIPlus_GraphicsDrawImage($hGFX, $hBMP, 0, 0)
EndFunc ;==>WM_PAINT
Func _Exit()
Exit
EndFunc ;==>_Exit
Func _Release()
[/autoit] [autoit][/autoit] [autoit]For $i = 0 To 255 Step 1
_GDIPlus_BrushDispose($hBrush[$i])
Next
_GDIPlus_GraphicsDispose($hBUF)
_GDIPlus_BitmapDispose($hBMP)
_GDIPlus_GraphicsDispose($hGFX)
_GDIPlus_Shutdown()
[/autoit] [autoit][/autoit] [autoit]EndFunc ;==>_Release
[/autoit]lg
M