Hier ein kleines Skript für den Silvester Abend.
Download: GDI+ Simple Firework build 2016-01-08 (inkl. Sound FX Files!)
Viel Spaß beim Ausprobieren.
Geschwindigkeit: ~17 FPS auf Intel Core i5 4300U @ 2.6 GHz bei einer Auflösung von 1600x900
Source Code
Spoiler anzeigen
AutoIt: GDI+ Simple Firework build 2016-01-08.au3
;coded by UEZ build 2016-01-08
;~ #AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#pragma compile(Icon, "c:\Program Files (x86)\AutoIt3\Icons\au3.ico")
#AutoIt3Wrapper_Run_Au3Stripper=y
#Au3Stripper_Parameters=/so /pe /rm
#AutoIt3Wrapper_Run_After=del /f /q "%scriptdir%\%scriptfile%_stripped.au3"
#include <GDIPlus.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include "BassConstants.au3"
#include "Bass.au3"
_GDIPlus_Startup()
Global $hGUI, $iFPS = 0, $iFrames = 0, $iShowFPS = 0, $fTimer, $bExit, $aAudio
Global Const $iW = @DesktopWidth, $iH = @DesktopHeight, $iWh = $iW / 2, $iHh = $iH / 2, $sTitle = "GDI+ Simple Firework by UEZ"
Global Const $fPi = ACos(-1), $fRad = $fPi / 180, $iMaxParticles = 51, $iFireworks = 10, $iParticleSize = 4
Global $iElements = 9, $aCoords[$iFireworks][$iElements + $iMaxParticles * 4 - 3] ;don't touch these values
AutoItSetOption("GUIOnEventMode", 1)
GDIPlus_SimpleFirework()
AutoItSetOption("GUIOnEventMode", 0)
_GDIPlus_Shutdown()
Func GDIPlus_SimpleFirework()
$bExit = False
$hGUI = GUICreate($sTitle & 0, $iW, $iH, 0, 0, $WS_POPUP)
GUISetState(@SW_SHOW, $hGUI)
WinSetTrans($hGUI, "", 0xF8)
GUISetCursor(16, 1)
;create canvas elements
Local Const $hDC = _WinAPI_GetDC($hGUI)
Local Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH)
Local Const $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC)
Local Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hHBitmap)
Local Const $hCanvas = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer)
_GDIPlus_GraphicsSetSmoothingMode($hCanvas, $GDIP_SMOOTHINGMODE_HIGHQUALITY)
_GDIPlus_GraphicsSetPixelOffsetMode($hCanvas, $GDIP_PIXELOFFSETMODE_HIGHQUALITY)
Local Const $hBrush = _GDIPlus_BrushCreateSolid(0xFFE0E0E0), _
$hBrush_Clr = _GDIPlus_BrushCreateSolid(0xA0000000), _
$hBrush_Txt = _GDIPlus_BrushCreateSolid(0x10202020), $hBrush_FPS = _GDIPlus_BrushCreateSolid(0xA0505050), _
$hFormat = _GDIPlus_StringFormatCreate(), $hFormat_FPS = _GDIPlus_StringFormatCreate(), _
$hFamily = _GDIPlus_FontFamilyCreate("Impact"), $hFamily_FPS = _GDIPlus_FontFamilyCreate("Arial"), _
$hFont = _GDIPlus_FontCreate($hFamily, $iH / 4.5), $hFont_FPS = _GDIPlus_FontCreate($hFamily_FPS, 8), _
$tLayout = _GDIPlus_RectFCreate(0, 0, $iW, $iH), $tLayout_FPS = _GDIPlus_RectFCreate(0, 0, 150, 32)
_GDIPlus_StringFormatSetAlign($hFormat, 1)
_GDIPlus_StringFormatSetLineAlign($hFormat, 1)
Local $iX, $iY, $j = -2^32 + 1, $bAudio = True
;init sound
_BASS_STARTUP()
_BASS_Init(0, -1, 44100, 0, "")
If @error Then $bAudio = False
Local $aAudio[$iFireworks][2], $hAudio_Whoa, $hAudio_BgNoise
For $iY = 0 To $iFireworks - 1 ;generated firework particles
GenCoordinates($iY, $aCoords, 1.5, 3.5, 1, 5.5)
If $bAudio Then
$aAudio[$iY][0] = _BASS_StreamCreateFile(False, @ScriptDir & "\" & Random(1, 7, 1) & ".mp3", 0, 0, 0)
$aAudio[$iY][1] = 0
EndIf
Next
$hAudio_Whoa = _BASS_StreamCreateFile(False, @ScriptDir & "\ApplauseWoah.mp3", 0, 0, 0)
$hAudio_BgNoise = _BASS_StreamCreateFile(False, @ScriptDir & "\BgNoise.mp3", 0, 0, 0)
_BASS_ChannelPlay($hAudio_BgNoise, True)
$iFPS = 0
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit_About")
AdlibRegister("CalcFPS", 1000)
Local $iAlpha, $iCounterFX = 0, $iCounterParticles = 0, $b
$fTimer = TimerInit()
Do
DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush_Clr, "float", 0, "float", 0, _
"float", $iW, "float", $iH) ;erase canvas background
_GDIPlus_GraphicsDrawStringEx($hCanvas, "Happy new year 2016", $hFont, $tLayout, $hFormat, $hBrush_Txt) ;draw background message text
For $iY = 0 To $iFireworks - 1 ;calculate and draw firework particles
If $aCoords[$iY][1] > $aCoords[$iY][4] Then ;draw rocket only until explosion
$aCoords[$iY][0] += $aCoords[$iY][2] ;x vector
$aCoords[$iY][1] -= Abs($aCoords[$iY][3] * 10) ;y vector should be in upper direction only
_GDIPlus_BrushSetSolidColor($hBrush, 0x60909090)
DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", $aCoords[$iY][0], "float", $aCoords[$iY][1], "float", 2, "float", 2)
$iCounterParticles += 1
For $iX = $iElements To UBound($aCoords, 2) - 5 Step 4
$aCoords[$iY][$iX] = $aCoords[$iY][0] ;copy x position
$aCoords[$iY][$iX + 1] = $aCoords[$iY][1] ;copy y position
Next
Else
For $iX = $iElements To UBound($aCoords, 2) - 5 Step 4
$aCoords[$iY][$iX] += $aCoords[$iY][$iX + 2] ;x coordinate
$aCoords[$iY][$iX + 1] += $aCoords[$iY][$iX + 3] + $aCoords[$iY][8] ;y coordinate
$aCoords[$iY][$iX + 2] *= 0.98 ;neg. accelaration of x vector
$aCoords[$iY][$iX + 3] *= 0.98 ;neg. accelaration of y vector
$iAlpha = $aCoords[$iY][6] > 0xFF ? 0xFF : $aCoords[$iY][6]
Switch $aCoords[$iY][7] ;choose color mode
Case 0
$b = True
Switch Mod($j, 2)
Case 0
_GDIPlus_BrushSetSolidColor($hBrush, Int($iAlpha) * 0x1000000 + 0x10000 * Random(0xD0, 0xFF, 1) + 0x100 * Random(0xD0, 0xFF, 1) + Random(0xD0, 0xFF, 1))
Case Else
_GDIPlus_BrushSetSolidColor($hBrush, Int($iAlpha) * 0x1000000 + $aCoords[$iY][5])
EndSwitch
Case Else
$b = False
_GDIPlus_BrushSetSolidColor($hBrush, Int($iAlpha) * 0x1000000 + $aCoords[$iY][5])
EndSwitch
;draw only visible particles
If BitAND($aCoords[$iY][$iX] > -1, $aCoords[$iY][$iX] < $iW, $aCoords[$iY][$iX + 1] > -1, $aCoords[$iY][$iX + 1] < $iH) Then
DllCall($__g_hGDIPDll, "int", "GdipFillEllipse", "handle", $hCanvas, "handle", $hBrush, _
"float", $aCoords[$iY][$iX], "float", $aCoords[$iY][$iX + 1], _
"float", $iParticleSize, "float", $iParticleSize) ;draw firework particles
$iCounterParticles += 1
EndIf
Next
If $b Then $j += 1
$aCoords[$iY][6] *= 0.933 ;decrease alpha channel
$aCoords[$iY][8] *= 1.075 ;gravity accelaration (y axis) -> earth's gravitational force simulation
If Not $aAudio[$iY][1] And $bAudio Then ;play audio fx
_BASS_ChannelPlay($aAudio[$iY][0], False)
$aAudio[$iY][1] = 1
$iCounterFX += 1
EndIf
If $aCoords[$iY][6] < 0x08 Then ;reset firework elements
$aAudio[$iY][1] = 0
GenCoordinates($iY, $aCoords)
EndIf
EndIf
Next
If $iCounterFX > 2 Then
_BASS_ChannelPlay($hAudio_Whoa, False)
EndIf
_GDIPlus_GraphicsDrawStringEx($hCanvas, "FPS: " & $iShowFPS & @CRLF & "Particles: " & $iCounterParticles, $hFont_FPS, $tLayout_FPS, $hFormat_FPS, $hBrush_FPS) ;draw background message text
_WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hDC_backbuffer, 0, 0, $SRCCOPY) ;blit drawn bitmap to GUI
$iCounterFX = 0
$iCounterParticles = 0
$iFPS += 1
$iFrames += 1
If $bExit Then ExitLoop
Until Not Sleep(10)
AdlibUnRegister("CalcFPS")
;release resources
_GDIPlus_FontDispose($hFont)
_GDIPlus_FontDispose($hFont_FPS)
_GDIPlus_FontFamilyDispose($hFamily)
_GDIPlus_FontFamilyDispose($hFamily_FPS)
_GDIPlus_StringFormatDispose($hFormat)
_GDIPlus_StringFormatDispose($hFormat_FPS)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_BrushDispose($hBrush_Clr)
_GDIPlus_BrushDispose($hBrush_Txt)
_GDIPlus_BrushDispose($hBrush_FPS)
_GDIPlus_GraphicsDispose($hCanvas)
_WinAPI_SelectObject($hDC, $DC_obj)
_WinAPI_DeleteObject($hHBitmap)
_WinAPI_ReleaseDC($hGUI, $hDC)
GUIDelete($hGUI)
If $bAudio Then
For $iY = 0 To $iFireworks - 1
_BASS_ChannelStop($aAudio[$iY][0])
Next
_BASS_ChannelStop($hAudio_Whoa)
_BASS_ChannelStop($hAudio_BgNoise)
_BASS_Free()
EndIf
EndFunc ;==>GDIPlus_SimpleFirework
Func GenCoordinates($iY, ByRef $aCoords, $fVXmin = 2.5, $fVXmax = 15.5, $fVYmin = 1.5, $fVYmax = 5.5)
Local $aColors[7] = [0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF7514, 0xFFFFFF, 0x40E0D0]
$aCoords[$iY][0] = $iWh ;x coordinate (x coordinate of starting point)
$aCoords[$iY][1] = $iH ;y coordinate (y coordinate of starting point)
$aCoords[$iY][2] = Random($fVXmin, $fVXmax) * (Random(0, 1, 1) = 0 ? -1 : 1) ;x vector (direction of rocket)
$aCoords[$iY][3] = Random($fVYmin, $fVYmax) * (Random(0, 1, 1) = 0 ? -1 : 1) ;y vector (direction of rocket)
$aCoords[$iY][4] = Random($iH * 0.15, $iH * 0.35) ;area of detonation
;~ $aCoords[$iY][5] = 0x10000 * Random(0x40, 0xE0, 1) + 0x100 * Random(0x40, 0xE0, 1) + Random(0x40, 0xE0, 1) ;random color
$aCoords[$iY][5] = $aColors[Random(0, 6, 1)] ;random color
$aCoords[$iY][6] = 0x250 ;alpha channel value
$aCoords[$iY][7] = Random(0, 1, 1) ;value for color mode
$aCoords[$iY][8] = 0.15 ;gravity accelaration (y axis) initial value
Local $iX, $fSpeed, $fRadius, $iFX = Random(1, 50, 1), $e = Random(5, 25), $h = 0, $g = 360 / ($iMaxParticles - 1), _
$j = 360 / 10, $jj = $j, $k = Random(0.5, 1.5), $kk = Random(1, 3.5), $l = 0
For $iX = $iElements To UBound($aCoords, 2) - 5 Step +4
Switch $iFX
Case 1 To 3
$fSpeed = Cos($g * $iFX * $e * $iX) * $e
$fRadius = $fSpeed / 2
Case 4 To 6
$fSpeed = Sin($iX / 7.85) * $e ;particle speed (explosion strength)
$fRadius = $fSpeed / 2
Case 7 To 9
$fSpeed = Tan($iX / 2) + $e ;particle speed (explosion strength)
$fRadius = $fSpeed / 2
Case 10 To 12
$fSpeed = Cos($iX / 2.5) + $e ;particle speed (explosion strength)
$fRadius = $fSpeed / 2
Case 13 To 15 ;create circular effect
$fSpeed = Random($e, $e + 0.333333) ;particle speed (explosion strength)
$fRadius = $fSpeed / 2
Case 16 To 18
$fSpeed = $e
$fRadius = $k
$h = $jj
$jj += $j
If $jj > 360 Then
$jj = $j - $l
$k += $kk
$l += Random(1, 15)
EndIf
Case Else
$fSpeed = Random(5, 25) ;particle speed (explosion strength)
$fRadius = $fSpeed / 2
EndSwitch
$aCoords[$iY][$iX + 2] = ($fSpeed + Cos($h * $fRad) * $fRadius) - $fSpeed ;x vector particle speed
$aCoords[$iY][$iX + 3] = ($fSpeed + Sin($h * $fRad) * $fRadius) - $fSpeed ;y vector particle speed
$h += $g ;next angle
Next
EndFunc ;==>GenCoordinates
Func _Exit_About()
$bExit = True
EndFunc ;==>_Exit_About
Func CalcFPS() ;display FPS
$iShowFPS = $iFPS & " / Ø " & Round($iFrames / TimerDiff($fTimer) * 1000, 4)
$iFPS = 0
EndFunc ;==>CalcFPS
Alles anzeigen