Hi,
ich habe mal eine weitere 'nutzlose' GDI+ Demo gebaut :D. Es ist eine grafische Diffusions Demo also eine Animation wie sich Flüssigkeiten ausgleichen.
viel Spaß damit.
Spoiler anzeigen
#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
;Defusions Demo GDI+ by Sprenger120
HotKeySet("{Esc}", "_Exit")
Global $RutschBeschleunigung = 2
Global $FallBeschleunigung = 5
Global $iTeilchenAnzahl = InputBox("GDI+ Diffusions Demo","Wie viele Teilchen?",151)
Global $iWidth = 470
Global $iHeight = 768
Global $Array_X = 0, $Array_Y = 1, $Array_Oben_Unten = 2, $Array_Status = 3, $Array_Farbe = 4, $Array_AbsObj = 5, $Array_WanderStatus = 6
Dim $aTeilchen[$iTeilchenAnzahl + 1][7] ;X|Y|Oben/Unten|Status|Farbe|Abstand zum Objekt|Wander Status
$aTeilchen[0][0] = False
$aTeilchen[0][1] = 0
$aTeilchen[0][1] = 0
Global $iMaxTeilchenAufstiegProVg = 1
Global $iWasserstand = 0 ;Höhe des Wasserstandes
Global $iObenUnten = 0
Global $iDiffusionsFortschritt = 1
_GDIPlus_Startup()
$hGUI = GUICreate("GDI+ Diffusion", $iWidth, $iHeight, -1, -1, $WS_POPUP)
GUISetState(@SW_SHOW)
$hGUIDC = _WinAPI_GetDC($hGUI)
$hBackpufferBitmap = _WinAPI_CreateCompatibleBitmap($hGUIDC, $iWidth, $iHeight)
$hBackpufferDC = _WinAPI_CreateCompatibleDC($hGUIDC)
_WinAPI_SelectObject($hBackpufferDC, $hBackpufferBitmap)
$hGraphics = _GDIPlus_GraphicsCreateFromHDC($hBackpufferDC)
_GDIPlus_GraphicsSetSmoothingMode($hGraphics, 2)
$hPen_Wand = _GDIPlus_PenCreate(0xFF000000, 10)
$hBrush_Rot = _GDIPlus_BrushCreateSolid(0xFFFF0000)
$hBrush_Blau = _GDIPlus_BrushCreateSolid(0xFF0000FF)
$hBrush_Schwarz = _GDIPlus_BrushCreateSolid(0xFF000000)
$hBrush_Wasserblau = _GDIPlus_BrushCreateSolid(0xAA99D9EA)
$hStringFormat = _GDIPlus_StringFormatCreate()
$hFamily = _GDIPlus_FontFamilyCreate("Arial")
$hFont = _GDIPlus_FontCreate($hFamily, 24, 2)
$tLayout = _GDIPlus_RectFCreate(100, 10, 0, 0)
While Sleep(10)
_GDIPlus_GraphicsClear($hGraphics, 0xFFFFFFFF)
_GDIPlus_GraphicsDrawString($hGraphics, "Zum beenden Escape drücken.", 10, 750)
_GDIPlus_GraphicsDrawLine($hGraphics, 50 + 1, 490, 410 - 1, 490) ;Membran
;Wasser zeichnen
If $iWasserstand > 498 Then _GDIPlus_GraphicsFillRect($hGraphics, 55, 739 - ($iWasserstand - 5), 355 - 1, $iWasserstand, $hBrush_Wasserblau)
;Becher zeichnen
_GDIPlus_GraphicsFillRect($hGraphics, 50, 240, 10, 500) ;links
_GDIPlus_GraphicsFillRect($hGraphics, 50, 740 - 1, 360, 10) ;unten
_GDIPlus_GraphicsFillRect($hGraphics, 410 - 1, 240, 10, 509) ;rechts
;Trichter zeichnen
_GDIPlus_GraphicsDrawLine($hGraphics, 0, 0, 120, 250, $hPen_Wand) ;links
_GDIPlus_GraphicsDrawLine($hGraphics, 470, 0, 350, 250, $hPen_Wand) ;rechts
Switch $iDiffusionsFortschritt
Case 1 ;Wasser reinfüllen
$sString = "Wasser einfüllen"
$aInfo = _GDIPlus_GraphicsMeasureString($hGraphics, $sString, $hFont, $tLayout, $hStringFormat)
_GDIPlus_GraphicsDrawStringEx($hGraphics, $sString, $hFont, $aInfo[0], $hStringFormat, $hBrush_Schwarz)
;Oben: 50,240,500
;Unten:50,240,500
$iWasserstand += 5
_GDIPlus_GraphicsFillRect($hGraphics, 130, 0, 20, 739 - $iWasserstand, $hBrush_Wasserblau) ;Wasserstrahl
_GDIPlus_GraphicsFillRect($hGraphics, 60, 739 - $iWasserstand, 350 - 1, $iWasserstand, $hBrush_Wasserblau) ;Wasser
If $iWasserstand > 498 Then $iDiffusionsFortschritt += 1
Case 2 ;Punkte in Behälter einfügen
;String zeichnen
$sString = "Teilchen dazugeben"
$aInfo = _GDIPlus_GraphicsMeasureString($hGraphics, $sString, $hFont, $tLayout, $hStringFormat)
_GDIPlus_GraphicsDrawStringEx($hGraphics, $sString, $hFont, $aInfo[0], $hStringFormat, $hBrush_Schwarz)
Switch $aTeilchen[0][0]
Case False
For $x = 1 To $iTeilchenAnzahl
$aTeilchen[$x][$Array_X] = Random(70, 400, 1)
$aTeilchen[$x][$Array_Y] = Random(50, 140, 1)
$aTeilchen[$x][$Array_Oben_Unten] = 2 ;Oben
$aTeilchen[$x][$Array_Status] = 0 ;fallend
$aTeilchen[$x][$Array_AbsObj] = 0
$aTeilchen[$x][$Array_WanderStatus] = 0
If $aTeilchen[0][1] > $aTeilchen[0][2] Then
$aTeilchen[$x][$Array_Farbe] = 2
$aTeilchen[0][2] += 1
EndIf
If $aTeilchen[0][1] < $aTeilchen[0][2] Then
$aTeilchen[$x][$Array_Farbe] = 1
$aTeilchen[0][1] += 1
EndIf
If $aTeilchen[0][1] = $aTeilchen[0][2] Then
Switch Random(0, 1, 1)
Case 0
$aTeilchen[$x][$Array_Farbe] = 1
$aTeilchen[0][1] += 1
Case 1
$aTeilchen[$x][$Array_Farbe] = 2
$aTeilchen[0][2] += 1
EndSwitch
EndIf
Next
$aTeilchen[0][0] = True
Case True ;es befinen sich Teilchen im Array
;Prüfen ob Trichter,Boden,Anderes stehendes Teilchen berührt wird
For $x = 1 To $iTeilchenAnzahl
For $i = 1 To $FallBeschleunigung
;Trichter
If PunktAufGeraden(1, 1, 120, 250, $aTeilchen[$x][$Array_X], $aTeilchen[$x][$Array_Y] + $i) Then
$aTeilchen[$x][$Array_AbsObj] = $i
$aTeilchen[$x][$Array_Status] = 1 ;Rutschend links
ExitLoop
EndIf
If PunktAufGeraden(350, 250, 470, 0, $aTeilchen[$x][$Array_X], $aTeilchen[$x][$Array_Y] + $i) Then
$aTeilchen[$x][$Array_Status] = 2 ;Rutschend rechts
$aTeilchen[$x][$Array_AbsObj] = $i
ExitLoop
EndIf
;~ If $Stapeln Then
;~ ;Anderes Teilchen
;~ For $k = 1 To $iTeilchenAnzahl
;~ If $k = $x Then ContinueLoop
;~ If $aTeilchen[$x][$Array_Y] < $aTeilchen[$k][$Array_Y] Then ContinueLoop
;~ If _RectCollision($aTeilchen[$x][$Array_X], $aTeilchen[$x][$Array_Y], 5, 5, $aTeilchen[$k][$Array_X], $aTeilchen[$k][$Array_Y], 5, 5) Then
;~ $aTeilchen[$x][$Array_Status] = 3
;~ $aTeilchen[$x][$Array_AbsObj] = $i
;~ ExitLoop 2
;~ EndIf
;~ Next
;~ EndIf
;Boden
If 730 = $aTeilchen[$x][$Array_Y] + $i Then
$aTeilchen[$x][$Array_Status] = 4 ;Boden
$aTeilchen[$x][$Array_AbsObj] = $i
ExitLoop
EndIf
Next
Next
;Teilchen weiter setzen
For $x = 1 To $iTeilchenAnzahl
If $aTeilchen[$x][$Array_AbsObj] Then
$aTeilchen[$x][$Array_Y] += $aTeilchen[$x][$Array_AbsObj]
$aTeilchen[$x][$Array_AbsObj] = 0
EndIf
Switch $aTeilchen[$x][$Array_Status]
Case 0
$aTeilchen[$x][$Array_Y] += $FallBeschleunigung
Case 1 ;rutschen links
;m=2
;n=10
$aTeilchen[$x][$Array_Y] = 2 * $aTeilchen[$x][$Array_X] + 10
$aTeilchen[$x][$Array_X] += $RutschBeschleunigung
If $aTeilchen[$x][$Array_X] > 120 Then $aTeilchen[$x][$Array_Status] = 0
Case 2 ;rutschen rechts
;m= -2
;n= 940
$aTeilchen[$x][$Array_Y] = -2 * $aTeilchen[$x][$Array_X] + 940
$aTeilchen[$x][$Array_X] -= $RutschBeschleunigung
If $aTeilchen[$x][$Array_X] > 120 Then $aTeilchen[$x][$Array_Status] = 0
EndSwitch
Next
;~ $FallBeschleunigung = Int($FallBeschleunigung * 1.15)
;Wenn erster Schritt abgeschlossen Fortschritt +1
$Weiter = True
For $x = 1 To $iTeilchenAnzahl
If $aTeilchen[$x][$Array_Status] = 0 Then
$Weiter = False
ExitLoop
EndIf
Next
If $Weiter Then
For $x = 1 To $iTeilchenAnzahl
$aTeilchen[$x][$Array_Oben_Unten] = 2; Unten
Next
$iDiffusionsFortschritt += 1
EndIf
EndSwitch
Case 3
$sString = "Diffusion"
$aInfo = _GDIPlus_GraphicsMeasureString($hGraphics, $sString, $hFont, $tLayout, $hStringFormat)
_GDIPlus_GraphicsDrawStringEx($hGraphics, $sString, $hFont, $aInfo[0], $hStringFormat, $hBrush_Schwarz)
$MengeOben = 0
$MengeUnten = 0
;Mengenverähltnisse ermitteln
;2 = Unten
;1 = Oben
For $x = 1 To $iTeilchenAnzahl
Switch $aTeilchen[$x][$Array_Oben_Unten]
Case 1,3;Oben
$MengeOben += 1
Case 2,4;Unten
$MengeUnten += 1
EndSwitch
Next
_GDIPlus_GraphicsDrawString($hGraphics, $MengeOben, 10, 250)
_GDIPlus_GraphicsDrawString($hGraphics, $MengeUnten, 10, 500)
;Oben: 50,240,500
;Unten:50,240,500
;Wander Status
;1 = Nach oben
;2 = nach unten
;Ausgleichen
$Aufstieg = 0
Switch $iObenUnten
Case 0
If $MengeUnten > $MengeOben Then
For $x = 1 To $iTeilchenAnzahl
If $aTeilchen[$x][$Array_WanderStatus] = 0 And $aTeilchen[$x][$Array_Oben_Unten] = 2 Then
$aTeilchen[$x][$Array_WanderStatus] = 1
$MengeUnten -= 1
$MengeOben += 1
$aTeilchen[$x][$Array_Oben_Unten] = 3;aufdem weg nach oben
$Aufstieg += 1
EndIf
If $MengeUnten = $MengeOben Or $Aufstieg = $iMaxTeilchenAufstiegProVg Then ExitLoop
Next
EndIf
$iObenUnten = 1
;~ _ArrayDisplay($aTeilchen)
Case 1
;~ #cs
;~ $Aufstieg = 0
If $MengeOben > $MengeUnten Then
For $x = 1 To $iTeilchenAnzahl
If $aTeilchen[$x][$Array_WanderStatus] = 0 And $aTeilchen[$x][$Array_Oben_Unten] = 1 Then
$aTeilchen[$x][$Array_WanderStatus] = 2
$MengeUnten += 1
$MengeOben -= 1
$aTeilchen[$x][$Array_Oben_Unten] = 4
$Aufstieg += 1
EndIf
If $MengeUnten = $MengeOben Or $Aufstieg = $iMaxTeilchenAufstiegProVg Then ExitLoop
Next
EndIf
;~ #ce
$iObenUnten = 0
EndSwitch
;Prüfen ob oben od. unten angekommen
For $x = 1 To $iTeilchenAnzahl
If Not $aTeilchen[$x][$Array_WanderStatus] Then ContinueLoop
For $i = 1 To $FallBeschleunigung
;Oben
If $aTeilchen[$x][$Array_Y] + $i < 254 Then
$aTeilchen[$x][$Array_WanderStatus] = 0
$aTeilchen[$x][$Array_Oben_Unten] = 1
$aTeilchen[$x][$Array_Y] = 255
ExitLoop
EndIf
;Unten
If $aTeilchen[$x][$Array_Y] > 730 + 2 Then
$aTeilchen[$x][$Array_WanderStatus] = 0
$aTeilchen[$x][$Array_Oben_Unten] = 2
$aTeilchen[$x][$Array_Y] = 731
ExitLoop
EndIf
Next
Next
;Teilchen bewegen
For $x = 1 To $iTeilchenAnzahl
Switch $aTeilchen[$x][$Array_WanderStatus]
Case 1 ;nach oben
$aTeilchen[$x][$Array_Y] -= $FallBeschleunigung
Case 2;nach unten
$aTeilchen[$x][$Array_Y] += $FallBeschleunigung
EndSwitch
Next
EndSwitch
;1 = Rot ; 2 = Blau
;Teilchen Zeichnen
For $x = 1 To $iTeilchenAnzahl
$hUseBrush = $hBrush_Rot
If $aTeilchen[$x][$Array_Farbe] = 2 Then $hUseBrush = $hBrush_Blau
_GDIPlus_GraphicsFillRect($hGraphics, $aTeilchen[$x][$Array_X], $aTeilchen[$x][$Array_Y], 5, 5, $hUseBrush)
Next
_WinAPI_BitBlt($hGUIDC, 0, 0, $iWidth, $iHeight, $hBackpufferDC, 0, 0, $SRCCOPY)
WEnd
Func _Exit()
$tLayout = 0
_GDIPlus_FontDispose($hFont)
_GDIPlus_FontFamilyDispose($hFamily)
_GDIPlus_StringFormatDispose($hStringFormat)
_GDIPlus_BrushDispose($hBrush_Schwarz)
_GDIPlus_BrushDispose($hBrush_Blau)
_GDIPlus_BrushDispose($hBrush_Rot)
_GDIPlus_BrushDispose($hBrush_Wasserblau)
_GDIPlus_PenDispose($hPen_Wand)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_Shutdown()
_WinAPI_ReleaseDC($hGUI, $hGUIDC)
_WinAPI_DeleteDC($hBackpufferDC)
_WinAPI_DeleteObject($hBackpufferBitmap)
Exit
EndFunc ;==>_Exit
Func _RectCollision($iX1, $iY1, $iWidth1, $iHeight1, $iX2, $iY2, $iWidth2, $iHeight2)
;Author: Faweyr
Return $iX1 + $iWidth1 > $iX2 And $iX1 < $iX2 + $iWidth2 And $iY1 + $iHeight1 > $iY2 And $iY1 < $iY2 + $iHeight2
EndFunc ;==>_RectCollision
Func PunktAufGeraden($Ax, $Ay, $Bx, $By, $Cx, $Cy)
Local $m, $n
;y = mx + n
$m = Int(($By - $Ay) / ($Bx - $Ax))
$n = Int($By - $m * $Bx)
If $m >= 0 Then
If $Cy = $m * $Cx + $n And $Cx <= $Bx And $Cy <= $By Then
Return True
Else
Return False
EndIf
EndIf
If $m <= 0 Then
If $Cy = $m * $Cx + $n And ($Cy < $Ay) Then
Return True
Else
Return False
EndIf
EndIf
EndFunc ;==>PunktAufGeraden