GDI+ drehende Dreiecke - Final

  • Dank der fleißigen Hilfe aus dem Forum ist mein erstes GDI+ Scriptbeispiel entstanden - was haltet ihr davon?
    Verbesserungsvorschläge sind gern gesehen

    Spoiler anzeigen
    [autoit]

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

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

    Opt("GUIOnEventMode", 1)
    OnAutoItExitRegister("__GDIPlus_Shutdown")
    _GDIPlus_Startup()

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

    Global $iRadius = 100 ; Größe des kleinen Dreiecks.
    Global $iWidth = 640, $iHeight = 640

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

    Global Const $deg2rad = ATan(1) * 4 / 180 ; Grad zu Radiant. ATan(1) * 4 = pi.

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

    Local Static $ibR = $iRadius, $iRad2 = $iRadius * 2 ; Starteinstellugnen für die Dreiecke
    Local Static $fRk = True, $fRg = False, $fRotK = True, $fRotG = False
    Local Static $iStepK = Random(1, 9, 1), $iStepG = Random(1, 9, 1)

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

    Dim $aPoly_k[4][2] = [[3]], $aPoly_g[4][2] = [[3]] ; Arrays für koordinaten der dreieckpunkte
    Dim $aM[2] = [$iWidth / 2, $iHeight / 2], $aCol[5] = [0x6F7261, 0x373252, 0xEBCC8B, 0x9E1B1B, 0xFCAB32] ; Anfangsfarben und Kreismitte

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

    $hGUI = GUICreate("GDI+ Beispiel - Drehende Dreiecke [SEuBo]", $iWidth, $iHeight)
    GUISetOnEvent(-3, "OnEvent_Eventhandler")
    GUIRegisterMsg($WM_PAINT, "WM_PAINT")

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

    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) ; Grafikobj. erstellen
    $hBrush = _GDIPlus_BrushCreateSolid(0xFF000000) ; Brush erzeugen
    $hPen = _GDIPlus_PenCreate(0xFF000000, 3) ; Pen erzeugen (schwarz)
    $hPenW = _GDIPlus_PenCreate(0xFFFFFFFF, 3) ; Pen (weiß)
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphic) ; Bitmap erstellen, und ihren
    $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap) ; Graphiccontext als backbuffer benutzen
    _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2)

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

    GUISetState()
    While 1 * Sleep(10)
    _Draw()
    WEnd

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

    ; #FUNCTION# ======================================================================================
    ; Name ..........: OnEvent_Eventhandler()
    ; Description ...: Handles GUI Events
    ; =================================================================================================
    Func OnEvent_Eventhandler()
    Switch @GUI_CtrlId
    Case -3
    Exit
    EndSwitch
    EndFunc ;==>OnEvent_Eventhandler

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

    ; #FUNCTION# ======================================================================================
    ; Name ..........: _Draw()
    ; Description ...: Calculates A, B and C Point of the triangle.
    ; Syntax ........: _Draw()
    ; Author ........: SEuBo
    ; Remarks .......: X = Cos(degree*180/pi) * radius
    ; Y = Sin(degree*180/pi) * radius
    ; The difference between the points is 120°. So all we have to do is adding 0, 120, 240 to
    ; the FIRST Points degree. (Which is $iK/$iG. K = klein (little), G = Groß (big))
    ;+
    ; To move the triangle, we just need to increase the first points degree. When its larger than
    ; 360, then we need to subtract 360.
    ; Link ..........: https://autoit.de/index.php?page=Thread&threadID=18504
    ; =================================================================================================
    Func _Draw()
    Local Static $iK = 0, $iG = 0

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

    Do
    ; Grad größer als 360? dann neue geschwindigkeit und drehrichtung
    If $iK >= 360 Then
    $iK -= 360
    $iStepK = Random(1, 9, 1)
    $fRotK = (Random(0, 1, 1) = 1)
    EndIf
    If $iG >= 360 Then
    $iG -= 360
    $iStepG = Random(1, 9, 1)
    $fRotG = (Random(0, 1, 1) = 1)
    EndIf

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

    ;Punkte berechnen. Siehe Remarks
    Local $iCos = (($fRotK = True) * (360 - $iK)) + (($fRotK = False) * ($iK))
    $aPoly_k[1][0] = $aM[0] + Cos($iCos * $deg2rad) * $iRadius
    $aPoly_k[1][1] = $aM[1] + Sin($iCos * $deg2rad) * $iRadius
    $aPoly_k[2][0] = $aM[0] + Cos(($iCos + 120) * $deg2rad) * $iRadius
    $aPoly_k[2][1] = $aM[1] + Sin(($iCos + 120) * $deg2rad) * $iRadius
    $aPoly_k[3][0] = $aM[0] + Cos(($iCos + 240) * $deg2rad) * $iRadius
    $aPoly_k[3][1] = $aM[1] + Sin(($iCos + 240) * $deg2rad) * $iRadius

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

    Local $iCos = (($fRotG = True) * (360 - $iG)) + (($fRotG = False) * ($iG))
    $aPoly_g[1][0] = $aM[0] + Cos($iCos * $deg2rad) * $iRad2
    $aPoly_g[1][1] = $aM[1] + Sin($iCos * $deg2rad) * $iRad2
    $aPoly_g[2][0] = $aM[0] + Cos(($iCos + 120) * $deg2rad) * $iRad2
    $aPoly_g[2][1] = $aM[1] + Sin(($iCos + 120) * $deg2rad) * $iRad2
    $aPoly_g[3][0] = $aM[0] + Cos(($iCos + 240) * $deg2rad) * $iRad2
    $aPoly_g[3][1] = $aM[1] + Sin(($iCos + 240) * $deg2rad) * $iRad2

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

    $iK += $iStepK
    $iG += $iStepG

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

    _GDIPlus_GraphicsClear($hBackbuffer, 0xFF000000 + $aCol[0]) ; altes Bild löschen
    _NewSize() ; Neue Farbe und Größe
    _NewColor()
    _GDIPlus_BrushSetSolidColor($hBrush, 0xFF000000 + $aCol[1]) ; Farbe einstellen
    _GDIPlus_GraphicsFillPolygon($hBackbuffer, $aPoly_g, $hBrush) ; Großes dreieck
    _GDIPlus_GraphicsDrawPolygon($hBackbuffer, $aPoly_g, $hPenW) ; Rand

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

    _GDIPlus_BrushSetSolidColor($hBrush, 0xFF000000 + $aCol[2])
    _GDIPlus_GraphicsFillEllipse($hBackbuffer, $aM[0] - $iRadius, $aM[1] - $iRadius, $iRadius * 2, $iRadius * 2, $hBrush) ; Kleiner Kreis
    _GDIPlus_GraphicsDrawEllipse($hBackbuffer, $aM[0] - $iRadius, $aM[1] - $iRadius, $iRadius * 2, $iRadius * 2, $hPen) ; Rand

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

    _GDIPlus_BrushSetSolidColor($hBrush, 0xFF000000 + $aCol[3])
    _GDIPlus_GraphicsFillPolygon($hBackbuffer, $aPoly_k, $hBrush) ; Kleines dreieck
    _GDIPlus_GraphicsDrawPolygon($hBackbuffer, $aPoly_k, $hPen) ; Rand

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

    _GDIPlus_BrushSetSolidColor($hBrush, 0x44000000 + $aCol[4]) ; Großer Kreis, mit tranparenz
    _GDIPlus_GraphicsFillEllipse($hBackbuffer, $aM[0] - $iRad2, $aM[1] - $iRad2, $iRad2 * 2, $iRad2 * 2, $hBrush)
    _GDIPlus_GraphicsDrawEllipse($hBackbuffer, $aM[0] - $iRad2, $aM[1] - $iRad2, $iRad2 * 2, $iRad2 * 2, $hPenW)

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

    WM_PAINT()
    Until $iK >= 360 Or $iG >= 360
    EndFunc ;==>_Draw

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

    ; #FUNCTION# ======================================================================================
    ; Name ..........: WM_PAINT()
    ; Description ...: Draws GDI+ Backbuffer to screen.
    ; Syntax ........: WM_PAINT()
    ; Author ........: SEuBo
    ; Remarks .......: This function is called, when a WM_PAINT event happens.
    ; Related .......: _Draw
    ; =================================================================================================
    Func WM_PAINT()
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, $iWidth, $iHeight)
    Sleep(10)
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_PAINT

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

    ; #FUNCTION# ======================================================================================
    ; Name ..........: __GDIPlus_Shutdown()
    ; Description ...: Clear GDI+ Resources and shut down then GDI+ Library
    ; Syntax ........: __GDIPlus_Shutdown()
    ; Author ........: SEuBo
    ; =================================================================================================
    Func __GDIPlus_Shutdown()
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_PenDispose($hPenW)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()
    EndFunc ;==>__GDIPlus_Shutdown

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

    ; #FUNCTION# ======================================================================================
    ; Name ..........: _NewSize()
    ; Description ...: Changes the radius of the circles.
    ; Syntax ........: _NewSize()
    ; Author ........: SEuBo
    ; Remarks .......: $fRk and $fRg determine, if the radius will increase(True) or decrease (false).
    ; When the radius exceeds a certain limit, the var State will switch.
    ; =================================================================================================
    Func _NewSize()
    Local $iStep = 1
    Switch $fRk
    Case True
    $iRadius += $iStep
    If $iRadius >= $ibR * 1.5 Then $fRk = False
    Case False
    $iRadius -= $iStep
    If $iRadius <= $ibR * 0.75 Then $fRk = True
    EndSwitch
    Switch $fRg
    Case True
    $iRad2 += $iStep
    If $iRad2 >= $ibR * 2 * 1.5 Then $fRg = False
    Case False
    $iRad2 -= $iStep
    If $iRad2 <= $ibR * 2 * 0.75 Then $fRg = True
    EndSwitch
    EndFunc ;==>_NewSize

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

    ; #FUNCTION# ======================================================================================
    ; Name ..........: _NewColor()
    ; Description ...: Changes the Color of all objects.
    ; Syntax ........: _NewColor()
    ; Return values .: None - Color Array is global.
    ; Author ........: SEuBo
    ; Remarks .......: It's done in 2 different loops, so the 2 triangles get different colors
    ; =================================================================================================
    Func _NewColor()
    Local $iStep = 5
    For $i = 1 To 2
    Local $itry = 0
    While $itry < 10
    $itry += 1
    Local $aRGB = _ColorGetRGB($aCol[$i]), $rnd = Random(0, 2, 1)
    Switch $fRg
    Case True
    If $aRGB[$rnd] + $iStep > 255 Then ContinueLoop
    $aRGB[$rnd] += $iStep
    Case False
    If $aRGB[$rnd] - $iStep < 0 Then ContinueLoop
    $aRGB[$rnd] -= $iStep
    EndSwitch
    $aCol[$i] = _ColorSetRGB($aRGB)
    ExitLoop
    WEnd
    Next
    For $i = 3 To 4
    Local $itry = 0
    While $itry < 10
    $itry += 1
    Local $aRGB = _ColorGetRGB($aCol[$i]), $rnd = Random(0, 2, 1)
    Switch $fRk
    Case True
    If $aRGB[$rnd] + $iStep > 255 Then ContinueLoop
    $aRGB[$rnd] += $iStep
    Case False
    If $aRGB[$rnd] - $iStep < 0 Then ContinueLoop
    $aRGB[$rnd] -= $iStep
    EndSwitch
    $aCol[$i] = _ColorSetRGB($aRGB)
    ExitLoop
    WEnd
    Next
    EndFunc ;==>_NewColor

    [/autoit]
  • Respekt sowas will ich auch können nur bin ich zu blöd für GDI+ zumindest zur zeit ^^

  • Kannst es ja noch zur Musik tanzen lassen (via bass.dll) oder so.


    Ich glaube das ist noch ein bisschen zu hart. ich mach erstmal ein paar rein grafische Sachen, damit ich auch verstehe, wie ich was berechnen muss.

    Sieht schön aus.
    Wenn man es noch schneller macht funzt auch Hypnose ^^
    MfG. PrideRage


    Ich kann ja noch unterschwellige Werbebotschaften ("überweis mir dein Geld") einbauen :rofl:

    bin ich zu blöd für GDI+

    Das Problem hab ich auch :D aber das Forum ist echt eine super Hilfe.

    Cooles Skript! :thumbup:
    Ist auf meinem Rechner auch schön schnell. Aber noch besser sieht es aus, wenn man das Fenster quadratisch macht (480x480 oder 640x640).

    Ich kann mir vorstellen, dass es auf meinem Rechner auch schön schnell ist. Allerdings sitze ich grade bei einem Kollegen, und sein Rechner stirbt mit den 512MB Ram schon beim Hochfahren von Vista :D

  • So habs jetzt nochmal n bisschen verändert. Die dreiecke bewegen sich jetzt unabhängig schnell voneinander. Richtungswechsel kommen gleich :P

    /EDIT: Und nochmal angepasst - jetzt ists geil!
    /EDIT2: Und jetzt das letzte mal. Die Richtung wird jetzt per Zufall berechnet. Sieht richtig cool aus 8)

  • Damit die CPU Last nicht so hoch ist, einfach ein Sleep(10) in Zeile 109 (Func WM_PAINT()) einfügen :!:

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯