GDI+ Spielerei - Feuerwerk

  • Hallo, meine Lieben!

    Die letzten Monate hatte ich kaum Zeit für das Forum.
    Dieser Zustand wird auch noch ein paar Monate anhalten...

    Quasi als Entschuldigung hab ich hier ein Script für euch:

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>

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

    Global Const $cPI = ATan(1) * 4
    Global Const $c2PI = $cPI * 2
    Global Const $cPI2 = $cPI / 2

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

    Global Const $LENS = 2000

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

    Opt("MustDeclareVars", 1)
    Opt("GUIOnEventMode", 1)

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

    Global $iWidth = 800
    Global $iHeight = 600

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

    _GDIPlus_Startup()

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

    ProgressOn("Please wait...", "creating big firework... 1/3")
    Global $aFW_B = _FireWork_Create($iWidth / 2, $iHeight / 2, 180, 7, 0xFFFFFFFF, $iWidth, $iHeight)
    ProgressOn("Please wait...", "creating mid firework... 2/3")
    Global $aFW_M = _FireWork_Create($iHeight / 2, $iHeight / 2, 120, 5, 0xFFFFFFFF, $iWidth, $iHeight)
    ProgressOn("Please wait...", "creating small firework... 3/3")
    Global $aFW_S = _FireWork_Create($iHeight / 2, $iHeight / 2, 60, 3, 0xFFFFFFFF, $iWidth, $iHeight)
    ProgressOff()

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

    Global $hGui = GUICreate("FireWork", $iWidth, $iHeight)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    Global $hDC = _WinAPI_GetDC($hGui)
    Global $hBMP = _WinAPI_CreateCompatibleBitmap($hDC, $iWidth, $iHeight)
    Global $hBmpTmp = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
    _WinAPI_DeleteObject($hBMP)
    $hBMP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBmpTmp)
    _GDIPlus_BitmapDispose($hBmpTmp)
    Global $hCDC = _WinAPI_CreateCompatibleDC($hDC)
    Global $hOBJ = _WinAPI_SelectObject($hCDC, $hBMP)
    Global $hGfxBuffer = _GDIPlus_GraphicsCreateFromHDC($hCDC)
    _GDIPlus_GraphicsClear($hGfxBuffer, 0xFF000000)

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

    Global $hBmpBG = _CreateBackGround()

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

    GUIRegisterMsg($WM_PAINT, "WM_PAINT")
    GUIRegisterMsg($WM_ERASEBKGND, "WM_PAINT")

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

    GUISetState()

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

    Global $aAttrib = _CreateImageAttributes()
    Global $tColorMX = DllStructCreate("float[5]; float[5]; float[5]; float[5]; float[5];")
    DllStructSetData($tColorMX, 1, 1, 1)
    DllStructSetData($tColorMX, 2, 1, 2)
    DllStructSetData($tColorMX, 3, 1, 3)
    DllStructSetData($tColorMX, 4, 1, 4)
    DllStructSetData($tColorMX, 5, 1, 5)

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

    Global $iTimer = TimerInit()
    While 1
    If TimerDiff($iTimer) >= 20 Then
    $iTimer = TimerInit()
    _Draw()
    EndIf
    WEnd

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

    Func _CreateImageAttributes()
    Local $aAttrib[7]
    Local $aResult

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

    For $i = 1 To 6
    $aResult = DllCall($ghGDIPDll, "int", "GdipCreateImageAttributes", "ptr*", 0)
    $aAttrib[$i] = $aResult[1]
    Next

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

    Return $aAttrib
    EndFunc ;==>_CreateImageAttributes

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

    Func _FireWork_Create($fCX, $fCY, $iCnt, $fSpeed, $iColor, $iW, $iH)
    Local $aExp[$iCnt + 1][40] = [[$iCnt]]
    Local $fPhi, $fTheta
    Local $fVX, $fVY, $fVZ, $fD

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

    For $i = 1 To $iCnt
    $fPhi = Random(0, $cPI2)
    $fTheta = Random(0, $c2PI)

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

    $fVX = Sin($fPhi) * Cos($fTheta) * $fSpeed
    $fVY = Sin($fPhi) * Sin($fTheta) * $fSpeed
    $fVZ = Cos($fPhi) * $fSpeed

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

    $fD = ($LENS - $fVZ)

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

    $aExp[$i][0] = $fCX
    $aExp[$i][1] = $fCY
    $aExp[$i][2] = $LENS * $fVX / $fD
    $aExp[$i][3] = $LENS * $fVY / $fD
    $aExp[$i][4] = Random(70, 122, 1)
    $aExp[$i][5] = Random(0.4, 1.6)

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

    For $j = 0 To 32 Step 2
    $aExp[$i][6 + $j] = $fCX
    $aExp[$i][7 + $j] = $fCY
    Next
    Next

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

    Local $aFW[129]
    Local $fX, $fY, $fR, $fTX, $fTY
    Local $hContext, $hBitmap
    Local $hPen = _GDIPlus_PenCreate($iColor, 1)
    Local $hBrush = _GDIPlus_BrushCreateSolid(BitOR(0x08000000, BitAND($iColor, 0x00FFFFFF)))

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

    Local $tCMX = DllStructCreate("float[5]; float[5]; float[5]; float[5]; float[5];")
    DllStructSetData($tCMX, 1, 1, 1)
    DllStructSetData($tCMX, 2, 1, 2)
    DllStructSetData($tCMX, 3, 1, 3)
    DllStructSetData($tCMX, 4, 0.85, 4)
    DllStructSetData($tCMX, 5, 1, 5)

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

    Local $aResult = DllCall($ghGDIPDll, "int", "GdipCreateImageAttributes", "ptr*", 0)
    Local $hAttr = $aResult[1]
    DllCall($ghGDIPDll, "int", "GdipSetImageAttributesColorMatrix", "ptr", $hAttr, "int", 1, "int", 1, "ptr", DllStructGetPtr($tCMX), "ptr", 0, "int", 0)

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

    Local $fSW = $fSpeed / 3
    Local $fSW2 = $fSW * 1.5, $fSW4 = $fSW * 3
    Local $aLog[33]
    For $i = 0 To 32 Step 2
    $aLog[$i] = Log($i * 5 / 32 + 2) * $fSW
    Next

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

    For $iStep = 1 To 128
    ProgressSet($iStep / 128 * 100)
    For $i = 1 To $iCnt
    $aExp[$i][2] += -$aExp[$i][2] / 48
    $aExp[$i][3] += ($aExp[$i][5] - $aExp[$i][3]) / 48

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

    For $j = 32 To 2 Step -2
    $aExp[$i][6 + $j] = $aExp[$i][4 + $j]
    $aExp[$i][7 + $j] = $aExp[$i][5 + $j]
    Next

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

    $aExp[$i][6] = $aExp[$i][0]
    $aExp[$i][7] = $aExp[$i][1]
    $aExp[$i][0] += $aExp[$i][2]
    $aExp[$i][1] += $aExp[$i][3]
    Next

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

    $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iW, "int", $iH, "int", 0, "int", 0x0026200A, "ptr", 0, "int*", 0)
    $hBitmap = $aResult[6]
    $aFW[$iStep] = $hBitmap
    $hContext = _GDIPlus_ImageGetGraphicsContext($aFW[$iStep])
    _GDIPlus_GraphicsSetSmoothingMode($hContext, 2)

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

    DllCall($ghGDIPDll, "int", "GdipDrawImageRectRectI", "hwnd", $hContext, "hwnd", $aFW[$iStep - 1], "int", 0, "int", 0, "int", $iW, "int", $iH, "int", 0, "int", 0, "int", $iW, "int", $iH, "int", 2, "ptr", $hAttr, "int", 0, "int", 0)

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

    For $i = 1 To $aExp[0][0]
    If $iStep > $aExp[$i][4] Then ContinueLoop
    $fX = $aExp[$i][0] + Random(-1, 1)
    $fY = $aExp[$i][1] + Random(-1, 1)
    ;DllCall($ghGDIPDll, "int", "GdipDrawEllipse", "handle", $hContext, "handle", $hPen, "float", $fX, "float", $fY, "float", 1, "float", 1)
    DllCall($ghGDIPDll, "uint", "GdipBitmapSetPixel", "hwnd", $hBitmap, "int", $fX, "int", $fY, "uint", $iColor)

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

    For $j = 0 To 32 Step 2
    $fR = $aLog[$j];Log($j * 5 / 32 + 2) * $fSW
    $fX = $aExp[$i][6 + $j] + Random(-$fR, $fR)
    $fY = $aExp[$i][7 + $j] + Random(-$fR, $fR)

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

    If (76 - $j) - $iStep > 0 Then
    ;DllCall($ghGDIPDll, "int", "GdipFillEllipse", "handle", $hContext, "handle", $hBrush, "float", $fX - $fSW2, "float", $fY - $fSW2, "float", $fSW4, "float", $fSW4)
    DllCall($ghGDIPDll, "int", "GdipFillRectangle", "handle", $hContext, "handle", $hBrush, "float", $fX - $fSW2, "float", $fY - $fSW2, "float", $fSW4, "float", $fSW4)
    ;DllCall($ghGDIPDll, "int", "GdipDrawEllipse", "handle", $hContext, "handle", $hPen, "float", $fX, "float", $fY, "float", 1, "float", 1)
    DllCall($ghGDIPDll, "uint", "GdipBitmapSetPixel", "hwnd", $hBitmap, "int", $fX, "int", $fY, "uint", $iColor)
    EndIf
    Next
    Next
    _GDIPlus_GraphicsDispose($hContext)
    Next

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

    DllCall($ghGDIPDll, "int", "GdipDisposeImageAttributes", "ptr", $hAttr)
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_BrushDispose($hBrush)

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

    $aFW[0] = 128
    Return $aFW
    EndFunc ;==>_FireWork_Create

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

    Func _FireWork_Dispose(ByRef $aFW)
    If Not IsArray($aFW) Then Return
    For $i = 1 To $aFW[0]
    _GDIPlus_BitmapDispose($aFW[$i])
    Next
    $aFW = 0
    EndFunc ;==>_FireWork_Dispose

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

    Func _CreateBackGround()
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", 0, "int", 0x0026200A, "ptr", 0, "int*", 0)
    Local $hBitmap = $aResult[6]
    Local $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetSmoothingMode($hContext, 2)
    _GDIPlus_GraphicsClear($hContext, 0xFF00000A)

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

    Local $hBrush1 = _GDIPlus_BrushCreateSolid(0x88FFFFFF)
    Local $hBrush2 = _GDIPlus_BrushCreateSolid(0x02FFFFFF)

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

    Local $fX, $fY, $fR, $fR1
    For $i = 1 To 250
    $fX = Random(0, $iWidth)
    $fY = Random(0, $iHeight)
    $fR = Random(0.2, 2.5)
    $fR1 = $fR * 4
    DllCall($ghGDIPDll, "int", "GdipFillEllipse", "handle", $hContext, "handle", $hBrush2, "float", $fX - $fR1, "float", $fY - $fR1, "float", $fR1 + $fR1, "float", $fR1 + $fR1)
    DllCall($ghGDIPDll, "int", "GdipFillEllipse", "handle", $hContext, "handle", $hBrush1, "float", $fX - $fR, "float", $fY - $fR, "float", $fR + $fR, "float", $fR + $fR)
    Next

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

    _GDIPlus_BrushDispose($hBrush1)
    _GDIPlus_BrushDispose($hBrush2)
    _GDIPlus_GraphicsDispose($hContext)
    Return $hBitmap
    EndFunc ;==>_CreateBackGround

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

    Func _Draw()
    Local Static $aStep[7] = [0, 5000, 129, 129, 129, 129, 129], $aWait[7] = [0, Random(140, 500, 1), Random(140, 500, 1), Random(140, 500, 1), Random(400, 1000, 1), Random(400, 1000, 1), Random(400, 1000, 1)]
    Local Static $aPos[7][2]

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

    Local $fR, $fG, $fB

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

    For $i = 1 To 6
    $aStep[$i] += 1
    If $aStep[$i] > $aWait[$i] Then
    $aStep[$i] = 1
    If $i <= 3 Then
    $aWait[$i] = Random(140, 500, 1)
    Else
    $aWait[$i] = Random(400, 1000, 1)
    EndIf
    $aPos[$i][0] = Random(-300, 300, 1)
    $aPos[$i][1] = Random(-200, 100, 1)

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

    $fR = Random(0, 1)
    $fG = Random(0, 1)
    $fB = Random(0, 1)

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

    Switch Random(0, 2, 1)
    Case 0
    $fR = 1
    Case 1
    $fG = 1
    Case Else
    $fB = 1
    EndSwitch

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

    DllStructSetData($tColorMX, 1, $fR, 1)
    DllStructSetData($tColorMX, 2, $fG, 2)
    DllStructSetData($tColorMX, 3, $fB, 3)
    DllCall($ghGDIPDll, "int", "GdipSetImageAttributesColorMatrix", "ptr", $aAttrib[$i], "int", 1, "int", 1, "ptr", DllStructGetPtr($tColorMX), "ptr", 0, "int", 0)
    EndIf
    Next

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

    _GDIPlus_GraphicsDrawImage($hGfxBuffer, $hBmpBG, 0, 0)

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

    If $aStep[1] <= 128 Then DllCall($ghGDIPDll, "int", "GdipDrawImageRectRectI", "hwnd", $hGfxBuffer, "hwnd", $aFW_B[$aStep[1]], "int", $aPos[1][0], "int", $aPos[1][1], "int", $iWidth, "int", $iHeight, "int", 0, "int", 0, "int", $iWidth, "int", $iHeight, "int", 2, "ptr", $aAttrib[1], "int", 0, "int", 0)
    If $aStep[2] <= 128 Then DllCall($ghGDIPDll, "int", "GdipDrawImageRectRectI", "hwnd", $hGfxBuffer, "hwnd", $aFW_M[$aStep[2]], "int", $aPos[2][0], "int", $aPos[2][1], "int", $iWidth, "int", $iHeight, "int", 0, "int", 0, "int", $iWidth, "int", $iHeight, "int", 2, "ptr", $aAttrib[2], "int", 0, "int", 0)
    If $aStep[3] <= 128 Then DllCall($ghGDIPDll, "int", "GdipDrawImageRectRectI", "hwnd", $hGfxBuffer, "hwnd", $aFW_S[$aStep[3]], "int", $aPos[3][0], "int", $aPos[3][1], "int", $iWidth, "int", $iHeight, "int", 0, "int", 0, "int", $iWidth, "int", $iHeight, "int", 2, "ptr", $aAttrib[3], "int", 0, "int", 0)

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

    If $aStep[4] <= 128 Then DllCall($ghGDIPDll, "int", "GdipDrawImageRectRectI", "hwnd", $hGfxBuffer, "hwnd", $aFW_B[$aStep[4]], "int", $aPos[4][0], "int", $aPos[4][1], "int", $iWidth, "int", $iHeight, "int", 0, "int", 0, "int", $iWidth, "int", $iHeight, "int", 2, "ptr", $aAttrib[4], "int", 0, "int", 0)
    If $aStep[5] <= 128 Then DllCall($ghGDIPDll, "int", "GdipDrawImageRectRectI", "hwnd", $hGfxBuffer, "hwnd", $aFW_M[$aStep[5]], "int", $aPos[5][0], "int", $aPos[5][1], "int", $iWidth, "int", $iHeight, "int", 0, "int", 0, "int", $iWidth, "int", $iHeight, "int", 2, "ptr", $aAttrib[5], "int", 0, "int", 0)
    If $aStep[6] <= 128 Then DllCall($ghGDIPDll, "int", "GdipDrawImageRectRectI", "hwnd", $hGfxBuffer, "hwnd", $aFW_S[$aStep[6]], "int", $aPos[6][0], "int", $aPos[6][1], "int", $iWidth, "int", $iHeight, "int", 0, "int", 0, "int", $iWidth, "int", $iHeight, "int", 2, "ptr", $aAttrib[6], "int", 0, "int", 0)

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

    _WinAPI_BitBlt($hDC, 0, 0, $iWidth, $iHeight, $hCDC, 0, 0, 0x00CC0020)
    EndFunc ;==>_Draw

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

    Func WM_PAINT($hWnd, $uMsgm, $wParam, $lParam)
    _WinAPI_BitBlt($hDC, 0, 0, $iWidth, $iHeight, $hCDC, 0, 0, 0x00CC0020)
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_PAINT

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

    Func _Exit()
    For $i = 1 To 6
    DllCall($ghGDIPDll, "int", "GdipDisposeImageAttributes", "ptr", $aAttrib[$i])
    Next
    _FireWork_Dispose($aFW_B)
    _FireWork_Dispose($aFW_M)
    _FireWork_Dispose($aFW_S)
    _GDIPlus_BitmapDispose($hBmpBG)
    _GDIPlus_GraphicsDispose($hGfxBuffer)
    _WinAPI_SelectObject($hCDC, $hOBJ)
    _WinAPI_DeleteObject($hBMP)
    _WinAPI_DeleteDC($hCDC)
    _WinAPI_ReleaseDC($hGui, $hDC)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>_Exit

    [/autoit]


    Läuft zwar nicht 100% flüssig, aber ich hoffe, es gefällt euch trotzdem...

    autoit.de/wcf/attachment/16922/

    Viel Spaß beim Ausprobieren!
    E

  • Wieder mal ein "echter" Eukalyptus! :thumbup:

    Zitat

    Die letzten Monate hatte ich kaum Zeit für das Forum.

    Da frag ich mich was du raushaust, wenn du mal richtig Zeit hast?! 8o

  • Das sieht klasse aus und Funktioniert auch bei mir 100% flüssig

    Zitat


    EIne Frage: Gibts irgendwo ein WinAPI Tutorial für AutoIt?

    das wäre auch mal meine Frage

    MfG, Facemix

    meine Spezialität: Windowstools für eine leichtere Arbeit am PC

    Nicht veröffentlicht


    nicht veröffentlichte Programme von mir

    - FTP Filereader
    - Youtube Kanal Player
    -GDI+ Countdown (bis zu einem Wunderbaren ereignis :) )

    MyPastebin

  • Hübsche Effekte :thumbup: ! Wie immer bei deinen GDI+ Kreationen :D.
    Und es läuft auch bei mir sehr flüssig (kein Wunder auf einem 4 GHz Core :P).

    Zitat

    EIne Frage: Gibts irgendwo ein WinAPI Tutorial für AutoIt?


    Ich bezweifle, dass es ein Tutorial gibt, dass die gesamte Windows API umfasst. Das ist nämlich verdammt viel Zeug :D. Ich lasse meine Meinung aber natürlich gerne widerlegen. Ich glaube ihr sucht eher ein GDI32 und ein GDIPlus Tutorial, diese beiden Dlls werden nämlich hauptsächlich in seinem Script verwendet (GDI+ mehr als das ursprüngliche GDI).

  • Zitat

    Eigentlich würde mich eine ASM-Umsetzung in Realtime reizen,

    Wäre die eine Variante, die andere wäre OpenCl.
    Den Code 1:1 in C zu übernehmen ist sicherlich einfacher als ASM. Wobei für EINZELNE Feuerwerke der ASM-Code meiner Erfahrung nach schneller ist.
    Aber wer will schon ein einzelnes Feuerwerk sehen, 20-30 Raketen gleichzeitig sollten es schon sein!
    Und dafür wäre OpenCl prädestiniert...