Moin,
Im Prinzip wollte ich einen Thread im Hilfebereich aufmachen, da ich hier etwas Hilfe (oder eine "zündende" Idee) brauche, aber es gibt schon ein funktionierendes Skript, also sind wir im Skriptbereich.
Das Tool soll folgendes tun: Einen Asteroiden (in 2D, GDI+) generieren.
Anforderungen (ein Teil davon ist zum Teil erfüllt, das meiste aber nicht)
- Der Asteroid soll möglichst nicht "schlecht" aussehen. (z.B. eine einfarbige Fläche wäre nicht sonderlich gut).
- Die Laufzeit sollte unter 100ms betragen um einen Asteroiden zu generieren (da später mal eine ganze Menge gebraucht werden und niemand 5 Min Ladezeit haben will).
- Der Asteroid braucht eine Art "Rohstoff" (in diesem Fall Grün, jede andere Farbe geht aber auch) der ohne Formveränderung des Asteroiden bei gleichem Seed Einstellbar sein sollte.
- ggf eine Beleuchung mit 1-2 Lichtquellen. (Hier habe ich keine Idee, wie soetwas in annehmbarer Zeit via GDI+ machbar ist. Ich glaube aber, dass es hier mal eine kleine GDI+ Demonstration mit Leuchteffekten gab.)
Natürlich könnte ich jetzt noch stundenlang weiterbasteln bis alles eingebaut ist was ich gerne hätte und anschließend herumoptimieren bis die Zeit (halbwegs) stimmt. Ich möchte aber ggf vorher ein paar Ideen von einigen GDI+ Leuten einholen
Für alle anderen Gilt: Habt Spaß und generiert euch Asteroiden (Und falls ihr interessante Farbkombinationen findet könnt ihr sie gerne posten)
#include-once
#include <GDIPlus.au3>
#include <Array.au3>
_GDIPlus_Startup()
Global $hAsteroid, $bRefresh = True
Global $bPaint = False
Global $iW = 400, $iH = 200
Global $hGUI = GUICreate('Asteroid Generator', $iW, $iH)
Global $hGfx = _GDIPlus_GraphicsCreateFromHWND($hGUI)
Global $hBmp = _GDIPlus_BitmapCreateFromScan0($iH, $iH)
Global $hBuf = _GDIPlus_ImageGetGraphicsContext($hBmp)
GUICtrlCreateEdit('Größe', $iH + 5, 5, 50, 20, 2049)
Global $hSli1 = GUICtrlCreateSlider($iH + 60, 5, $iW - $iH - 65 - 50, 20)
Global $hLab1 = GUICtrlCreateEdit('76', $iW - 50, 5, 45, 20, 2049)
GUICtrlSetData($hSli1, Round(GUICtrlRead($hLab1)/1.5 - 4, 0))
GUICtrlCreateEdit('Col3%', $iH + 5, 30, 50, 20, 2049)
Global $hSli2 = GUICtrlCreateSlider($iH + 60, 30, $iW - $iH - 65 - 50, 20)
Global $hLab2 = GUICtrlCreateEdit('50', $iW - 50, 30, 45, 20, 2049)
GUICtrlSetData($hSli2, GUICtrlRead($hLab2))
GUICtrlCreateEdit('Seed', $iH + 5, 55, 50, 20, 2049)
Global $hBtn3 = GUICtrlCreateButton('Random', $iH + 60, 55, $iW - $iH - 65 - 50, 20)
Global $hLab3 = GUICtrlCreateEdit(Random(0, 999999, 1), $iW - 50, 55, 45, 20, 1)
GUICtrlCreateEdit('Col 1', $iH + 5, 80, 62, 18, 2049)
GUICtrlCreateEdit('Col 2', $iH + 69, 80, 62, 18, 2049)
GUICtrlCreateEdit('Col 3', $iH + 133, 80, 62, 18, 2049)
Global $hCol1 = GUICtrlCreateEdit('FF602000', $iH + 5, 100, 62, 18, 1)
GUICtrlSetFont(-1, 7, 400, 0, 'Arial', 5)
Global $hCol2 = GUICtrlCreateEdit('FF909090', $iH + 69, 100, 62, 18, 1)
GUICtrlSetFont(-1, 7, 400, 0, 'Arial', 5)
Global $hCol3 = GUICtrlCreateEdit('FF00FF00', $iH + 133, 100, 62, 18, 1)
GUICtrlSetFont(-1, 7, 400, 0, 'Arial', 5)
Global $hNew = GUICtrlCreateButton('Redraw', $iH + Round(($iW - $iH)/2, 0) - 50, 125, 100, 25)
Global $hSave = GUICtrlCreateButton('Save', $iH + Round(($iW - $iH)/2, 0) - 50, 155, 100, 25)
GUISetState()
GUIRegisterMsg(0xF, 'WM_PAINT')
WM_PAINT()
While True
Switch GUIGetMsg()
Case -3
ExitLoop
Case $hSli1, $hSli2
$xTmp = Round(1.5 * GUICtrlRead($hSli1) + 8, 0)
GUICtrlSetData($hLab1, $xTmp)
GUICtrlSetData($hLab2, GUICtrlRead($hSli2))
$bRefresh = True
Case $hBtn3
GUICtrlSetData($hLab3, Random(0, 999999, 1))
$bRefresh = True
Case $hNew
$bRefresh = True
Case $hSave
$xTmp = FileSaveDialog('Zieldatei eingeben', @ScriptDir, '(*.png)')
_GDIPlus_ImageSaveToFile($hAsteroid, $xTmp)
EndSwitch
If $bRefresh Then
$bRefresh = False
$bPaint = False
$xTmp = Round(1.5 * GUICtrlRead($hSli1) + 8, 0)
_GDIPlus_BitmapDispose($hAsteroid)
$hAsteroid = _AsteroidCreateBitmap($xTmp, GUICtrlRead($hSli2), GUICtrlRead($hLab3), '0x' & GUICtrlRead($hCol1), '0x' & GUICtrlRead($hCol2), '0x' & GUICtrlRead($hCol3))
_GDIPlus_GraphicsClearCheckboard($hBuf, 0xFF9F9F9F, 0xFFE2E2E2, 200, 200)
_GDIPlus_GraphicsDrawImage($hBuf, $hAsteroid, Round($iH/2 - $xTmp/2, 0), Round($iH/2 - $xTmp/2, 0))
$bPaint = True
WM_PAINT()
EndIf
WEnd
Func _GDIPlus_GraphicsClearCheckboard($hGFX, $iCol1, $iCol2, $iW, $iH)
Local $hBRU1 = _GDIPlus_BrushCreateSolid($iCol1)
Local $hBRU2 = _GDIPlus_BrushCreateSolid($iCol2)
Local $iD = Round(($iW ^ 2 + $iH ^ 2) ^ 0.25 / 2, 0)
For $x = 0 To Int($iW / $iD) - 1 Step 1
For $y = 0 To Int($iH / $iD) - 1 Step 1
_GDIPlus_GraphicsFillRect($hGfx, $x * $iD, $y * $iD, $iD, $iD, IsInt($x/2) ? (IsInt($y/2) ? $hBRU1 : $hBRU2) : (IsInt($y/2) ? $hBRU2 : $hBRU1))
Next
Next
_GDIPlus_BrushDispose($hBRU1)
_GDIPlus_BrushDispose($hBRU2)
EndFunc
_GDIPlus_BitmapDispose($hAsteroid)
_GDIPlus_GraphicsDispose($hBuf)
_GDIPlus_BitmapDispose($hBmp)
_GDIPlus_GraphicsDispose($hGfx)
Func WM_PAINT()
If $bPaint Then _GDIPlus_GraphicsDrawImage($hGfx, $hBmp, 0, 0)
EndFunc
;~ SRandom(@MSEC + @SEC*1000 + @MIN*1000*60)
;~ Global $t = TimerInit()
;~ For $i = 1 To 4 Step 1
;~ _AsteroidCreateBitmap(48, 0, $i*2)
;~ Next
;~ ConsoleWrite(Round(TimerDiff($t)/($i-1),0) & ' ms' & @CRLF)
_GDIPlus_Shutdown()
Func _AsteroidCreateBitmap($iSizePx = 32, $iCrystalPercent = 25, $iSeed = Default, $iCol1 = 0xFF602000, $iCol2 = 0xFF909090, $iCol3 = 0xFF00FF00)
Local $hBmp = _GDIPlus_BitmapCreateFromScan0($iSizePx, $iSizePx)
Local $hPen = _GDIPlus_PenCreate(0x40000000, $iSizePx^0.25/1.5)
Local $hBru = _GDIPlus_BrushCreateSolid()
Local $hGfx = _GDIPlus_ImageGetGraphicsContext($hBmp)
Local Const $fDegToRad = 3.141592653589793 / 180
_GDIPlus_GraphicsSetSmoothingMode($hGfx, 2)
_GDIPlus_GraphicsSetPixelOffsetMode($hGfx, 2)
If $iSeed <> Default Then SRandom($iSeed)
; Schritt 1: Umriss definieren
Local $iPoints = Round($iSizePx^0.45*2.5, 0), $aPoints[$iPoints + 1][2] = [[$iPoints, 0]], $iRandomOffset
For $i = 1 To $iPoints Step 1
$iRandomOffset = Random(-90/$iPoints, 90/$iPoints) * $fDegToRad
$aPoints[$i][0] = ($iSizePx * 0.4 * Cos($i/($iPoints)*$fDegToRad*360 + $iRandomOffset) + $iSizePx * 0.5) * Random(0.9^(1/($iPoints^0.25)), 1.1^(1/($iPoints^0.25)))
$aPoints[$i][1] = ($iSizePx * 0.4 * Sin($i/($iPoints)*$fDegToRad*360 + $iRandomOffset) + $iSizePx * 0.5) * Random(0.9^(1/($iPoints^0.25)), 1.1^(1/($iPoints^0.25)))
Next
_PointsStauchen($aPoints, $iSizePx * 0.5, Random(0.75, 1))
_PointsRotate($aPoints, $iSizePx * 0.5, $iSizePx * 0.5, Random(0, 360))
; Schritt 2: Textur Erzeugen
Local $hTex = _TextureCreate($iSizePx, $iSizePx, $iCol1, $iCol2, $iCol3, $iCrystalPercent / 100)
; Schritt 3: Zeichnen
_GDIPlus_GraphicsClear($hGfx, 0)
_GDIPlus_GraphicsFillPolygon($hGfx, $aPoints, $hTex)
_GDIPlus_PenSetAlignment($hPen, 1)
_GDIPlus_GraphicsDrawPolygon($hGfx, $aPoints, $hPen)
_GDIPlus_PenSetWidth($hPen, 0.75)
_GDIPlus_PenSetColor($hPen, 0xEE000000)
_GDIPlus_PenSetAlignment($hPen, 0)
_GDIPlus_GraphicsDrawPolygon($hGfx, $aPoints, $hPen)
;~ _GDIPlus_ImageSaveToFile($hBmp, Random(100, 999, 1) & '.png')
_GDIPlus_BrushDispose($hTex)
_GDIPlus_GraphicsDispose($hGfx)
_GDIPlus_BrushDispose($hBru)
_GDIPlus_PenDispose($hPen)
;~ _GDIPlus_BitmapDispose($hBmp)
Return $hBmp
EndFunc
Func _TextureCreate($iW, $iH, $iCol1, $iCol2, $iCol3, $iMenge = 0.5)
; iCol1 : Erste Grundfarbe des Ateroiden
; iCol2 : Zweite Grundfarbe des Asteroiden
; iCol3 : Farbe von besonderem Gestein auf der Oberfläche
; iMenge : Menge von 0 bis 1 des besonderen Gesteins
Local $hBmp = _GDIPlus_BitmapCreateFromScan0($iW, $iH)
Local $hGfx = _GDIPlus_ImageGetGraphicsContext($hBmp)
Local $hBRU = _GDIPlus_BrushCreateSolid()
Local $aPoints = [[2, 0], [-$iW/10, -$iH/10], [$iW*1.1, $iH*1.1]]
_PointsRotate($aPoints, $iW/2, $iH/2, Random(0, 360))
Local $hLine = _GDIPlus_LineBrushCreate($aPoints[1][0], $aPoints[1][1], $aPoints[2][0], $aPoints[2][1], $iCol1, $iCol2)
_GDIPlus_GraphicsSetSmoothingMode($hGfx, 2)
; Grundfarbe
_GDIPlus_GraphicsFillRect($hGfx, -$iW/10, -$iH/10, $iW * 1.1, $iH*1.1, $hLine)
Local $iD, $aMulti = [4, 3, 2, 2]
For $n = 0 To 3 Step 1
For $i = 0 To Round(($iW ^ 2 + $iH ^ 2) ^ 0.5 * $aMulti[$n], 0) Step 1
_GDIPlus_BrushSetSolidColor($hBRU, BitOR('0x' & Hex(Int(Round(Random(24 / $aMulti[$n], 56 / $aMulti[$n])*$iMenge, 0)), 2) & '000000', BitAND($iCol3, 0xFFFFFF)))
$iD = Random($iW/18*$aMulti[$n], $iW/12*$aMulti[$n]) * ((Random(0, 4, 1) = 0) ? 4 : 1)
$aPoints = _PointsFromRect(0, 0, $iD, $iD)
_PointsRotate($aPoints, $iD/2, $iD/2, Random(0, 360))
_PointsTranslate($aPoints, Random(-$iD, $iW + $iD), Random(-$iD, $iH + $iD))
_GDIPlus_GraphicsFillPolygon($hGfx, $aPoints, $hBRU)
_GDIPlus_BrushSetSolidColor($hBRU, BitOR('0x' & Hex(Int(Random(16 / $aMulti[$n], 48 / $aMulti[$n], 1)), 2) & '000000', BitAND($iCol1, 0xFFFFFF)))
$iD = Random($iW/9*$aMulti[$n], $iW/4*$aMulti[$n])
$aPoints = _PointsFromRect(0, 0, $iD, $iD)
_PointsRotate($aPoints, $iD/2, $iD/2, Random(0, 360))
_PointsTranslate($aPoints, Random(-$iD, $iW + $iD), Random(-$iD, $iH + $iD))
_GDIPlus_GraphicsFillPolygon($hGfx, $aPoints, $hBRU)
_GDIPlus_BrushSetSolidColor($hBRU, BitOR('0x' & Hex(Int(Random(16 / $aMulti[$n], 48 / $aMulti[$n], 1)), 2) & '000000', BitAND($iCol2, 0xFFFFFF)))
$iD = Random($iW/12*$aMulti[$n], $iW/8*$aMulti[$n])
$aPoints = _PointsFromRect(0, 0, $iD, $iD)
_PointsRotate($aPoints, $iD/2, $iD/2, Random(0, 360))
_PointsTranslate($aPoints, Random(-$iD, $iW + $iD), Random(-$iD, $iH + $iD))
_GDIPlus_GraphicsFillPolygon($hGfx, $aPoints, $hBRU)
_GDIPlus_BrushSetSolidColor($hBRU, '0x' & Hex(Int(Random(8, 16, 1)), 2) & '000000')
$iD = Random($iW/12*$aMulti[$n], $iW/8*$aMulti[$n])
$aPoints = _PointsFromRect(0, 0, $iD, $iD)
_PointsRotate($aPoints, $iD/2, $iD/2, Random(0, 360))
_PointsTranslate($aPoints, Random(-$iD, $iW + $iD), Random(-$iD, $iH + $iD))
_GDIPlus_GraphicsFillPolygon($hGfx, $aPoints, $hBRU)
Next
Next
;~ _GDIPlus_ImageSaveToFile($hBmp, Random(100, 999, 1) & '.png')
Local $hTex = _GDIPlus_TextureCreate($hBmp)
_GDIPlus_BrushDispose($hLine)
_GDIPlus_BrushDispose($hBru)
_GDIPlus_GraphicsDispose($hGfx)
_GDIPlus_BitmapDispose($hBmp)
Return $hTex
EndFunc
Func _PointsTranslate(ByRef $aPoints, $iX, $iY)
For $i = 1 To $aPoints[0][0] Step 1
$aPoints[$i][0] += $iX
$aPoints[$i][1] += $iY
Next
EndFunc
Func _PointsStauchen(ByRef $aPoints, $mY, $nFaktor = 1)
For $i = 1 To $aPoints[0][0] Step 1
$aPoints[$i][1] = ($aPoints[$i][1] - $mY) * $nFaktor + $mY
Next
EndFunc
Func _PointsRotate(ByRef $aPoints, $mX, $mY, $nDegAngle)
Local $x, $fAngle = $nDegAngle / 180 * 3.141593
For $i = 1 To $aPoints[0][0] Step 1
$x = $mX + Cos($fAngle) * ($aPoints[$i][0] - $mX) - Sin($fAngle) * ($aPoints[$i][1] - $mY)
$aPoints[$i][1] = $mY + Sin($fAngle) * ($aPoints[$i][0] - $mX) + Cos($fAngle) * ($aPoints[$i][1] - $mY)
$aPoints[$i][0] = $x
Next
EndFunc
Func _PointsFromRect($iX, $iY, $iW, $iH)
Local $aPoints[5][2]
$aPoints[0][0] = 4
$aPoints[1][0] = $iX
$aPoints[1][1] = $iY
$aPoints[2][0] = $iX + $iW
$aPoints[2][1] = $iY
$aPoints[3][0] = $iX + $iW
$aPoints[3][1] = $iY + $iH
$aPoints[4][0] = $iX
$aPoints[4][1] = $iY + $iH
Return $aPoints
EndFunc
Alles anzeigen
PS: Ich weiß, dass das Skript sehr Spaghetticodeartig ist. Optimierungen sind erstmal nicht nötig, solange das Ergebnis noch nicht stimmt
lg
Mars