GDI+ Basics
____________________________________
Als erstes brauchen wir eine GUI die wir im Vollbildmodus und im $WS_POPUP stil (das heisst ohne diesen Rand oben) starten.
Wenn wir das haben, müssen wir GDI+ zu den Includes hinzufügen und es bei Programmstart hochfahren lassen.
Jetzt müssen wir die Graphics handle für die GUI erstellen lassen. Aber Achtung! Es gibt 2 methoden. Die die hier (bei den basics) gezeigt wird ist einfacher, flackert aber ein Bisschen. Schaut es aber bitte trotzdem durch und geht nicht direkt zu den komplizierten Sachen, weil sonst nur Verwirrung entsteht.
So. Jetzt haben wir eine GUI und die dazugehörige Graphicshandle. Das was wir als nächstes brauchen sind ein paar sachen die wir da draufzeichnen lassen.
Code:
$WS_POPUP=0x80000000
$hGui=Guicreate("Titel",@DesktopWidth,@DesktopHeight,0,0,$WS_POPUP)
guisetstate()
Code:
#include <GDIPlus.au3> ;die GDIPlus befehle laden
_Gdiplus_Startup() ;Ohne _GDIPlus_Startup() funktioniert nichts
$WS_POPUP=0x80000000
$hGui=GuiCreate("Titel",@DesktopWidth,@DesktopHeight,0,0,$WS_POPUP)
GUISetState() ;Die GUI sichtbar machen
Code:
#include <GDIPlus.au3> ;die GDIPlus befehle laden
_Gdiplus_Startup() ;Ohne _GDIPlus_Startup() funktioniert nichts
$WS_POPUP=0x80000000
$hGui=GuiCreate("Titel",@DesktopWidth,@DesktopHeight,0,0,$WS_POPUP)
GuiSetState() ;Die GUI sichtbar machen
$hGraphics=_GDIPlus_GraphicsCreateFromHWND($hGui)
Code:
#include <GDIPlus.au3> ;die GDIPlus befehle laden
_Gdiplus_Startup() ;Ohne _GDIPlus_Startup() funktioniert nichts
$WS_POPUP=0x80000000
$hGui=Guicreate("Titel",@DesktopWidth,@DesktopHeight,0,0,$WS_POPUP)
GUISetState()
$hGraphics=_GDIPlus_GraphicsCreateFromHWND($hGui)
While GUIGetMsg()<>-3
For $i=100 To 500
_GDIPlus_GraphicsClear($hGraphics,0xFFFFFFFF) ;Den Bildschirm leeren.
_GDIPlus_GraphicsDrawString($hGraphics,"Ich bin ein Text",$i,200) ;Guckt in die AutoIt3 Hilfe. Dort seht ihr mehr Sachen die man zeichnen lassen kann, und wie man sie benutzt.
Sleep(30) ;Damit es nicht so flackert und der Text nicht so schnell durch den Bildschirm läuft
Next
WEnd
GDI+ Fortgeschrittenes
____________________________________
Wie ich oben bei den basics gesagt habe gibt es eine andere methode die nicht flackert. und zwar wird bei dieser nicht direkt auf das fenster gezeichnet, sondern erst auf einen zwischenbuffer, und dann auf das fenster. Die ersten 5 zeilen vom Basics script kann ich übernehmen da sie richtig sind.
jetzt müssen wir die 3 Graphics erstellen. fangen wir mit der ersten an. Sie ist eigentlich das selbe wie das was wir bei den basics gelernt haben. nur sind die anderen 2 Graphics handles neu.
Die zweite Graphicshandle ist ein bild welches es von der ersten Graphicshandle erstellt.
ich habe @DesktopWidth und @DesktopHeight benutzt weil die GUI so groß ist.
Die dritte Graphicshandle ist die zwischenbuffer-leinwand auf die man draufmalt.
Am besten sollte man wann auch immer es geht Arrays benutzen damit man die übersicht besser behält. Unser script sieht dann mit den in eine Array gepackten Graphicshandles so aus:
Zeichnen tut man immer auf die dritte Graphicshandle. Wenn man fertig mit zeichnen ist, überträgt man die zweite graphicshandle auf das fenster.
Code:
#include <GDIPlus.au3> ;die GDIPlus befehle laden
_Gdiplus_Startup() ;Ohne _GDIPlus_Startup() funktioniert nichts
$WS_POPUP=0x80000000
$hGui=Guicreate("Titel",@DesktopWidth,@DesktopHeight,0,0,$WS_POPUP)
GUISetState()
Code:
$hGraphics1=_GDIPlus_GraphicsCreateFromHWND($hGui)
Code:
$hGraphics2=_GDIPlus_BitmapCreateFromGraphics(@DesktopWidth,@DesktopHeight,$hGraphics1)
Die dritte Graphicshandle ist die zwischenbuffer-leinwand auf die man draufmalt.
Code:
$hGraphics3=_GDIPlus_ImageGetGraphicsContext($hGraphics2) ;Wie vom englischen übersetzt wird aus dem bild (in diesem fall die Graphicshandle Nr.2) eine Graphicshandle gezogen
Code:
#include <GDIPlus.au3> ;die GDIPlus befehle laden
_Gdiplus_Startup() ;Ohne _GDIPlus_Startup() funktioniert nichts
Global $hGraphics[3] ;hGraphics als eine 1Dimensionale Array mit 3 Elementen deklarieren
$WS_POPUP=0x80000000
$hGui=Guicreate("Titel",@DesktopWidth,@DesktopHeight,0,0,$WS_POPUP)
GUISetState()
$hGraphics[0]=_GDIPlus_GraphicsCreateFromHWND($hGui)
$hGraphics[1]=_GDIPlus_BitmapCreateFromGraphics(@DesktopWidth,@DesktopHeight,$hGraphics[0])
$hGraphics[2]=_GDIPlus_ImageGetGraphicsContext($hGraphics[1])
Code:
#include <GDIPlus.au3> ;die GDIPlus befehle laden
_Gdiplus_Startup() ;Ohne _GDIPlus_Startup() funktioniert nichts
Global $hGraphics[3] ;hGraphics als eine 1Dimensionale Array mit 3 Elementen deklarieren
$WS_POPUP=0x80000000
$hGui=Guicreate("Titel",@DesktopWidth,@DesktopHeight,0,0,$WS_POPUP)
GUISetOnEvent(-3,"_Exit")
GUISetState()
$hGraphics[0]=_GDIPlus_GraphicsCreateFromHWND($hGui)
$hGraphics[1]=_GDIPlus_BitmapCreateFromGraphics(@DesktopWidth,@DesktopHeight,$hGraphics[0])
$hGraphics[2]=_GDIPlus_ImageGetGraphicsContext($hGraphics[1])
While GUIGetMsg()<>-3
For $i=100 To 500
_GDIPlus_GraphicsClear($hGraphics[2],0xFFFFFFFF) ;Den Buffer Leeren
_GDIPlus_GraphicsDrawRect($hGraphics[2],$i,200,100,100) ;Auf Buffer zeichnen
_GDIPlus_GraphicsDrawImage($hGraphics[0],$hGraphics[1],0,0) ;Buffer auf Bildschirm übertragen
Next
WEnd
_Exit()
Func _Exit() ;ist nicht wirklich nötig, kann aber gemacht werden.
_GDIPlus_GraphicsDispose($hGraphics[2])
_GDIPlus_BitmapDispose($hGraphics[1])
_GDIPlus_GraphicsDispose($hGraphics[0])
EndFunc
Mathematik Sin,Cos: Wie es funktioniert + kleines Beispiel
____________________________________
Erstmal will ich erläutern, dass die sin,tan,cos,asin,acos und atan NICHT mit gradzahlen sondern mit radianten arbeiten. um eine gradzahl in radianten umzuwandeln muss man (pi/180)*Gradzahl rechnen.
Hier ersteinmal eine Formel, die ihr nachdem ihr den darauf folgenden text gelesen habt, untersuchen sollt und (hoffentlich) verstehen werdet.
Die formel berechnet neue koordinaten mithilfe von den alten koordinaten, den winkel und die distanz die "gelaufen" werden soll.
Code:
$x=100
$y=100
$Distanz=25
$Winkel=DegToRad(45)
$x+=Cos($Winkel)*$Distanz
$y+=Sin($Winkel)*$Distanz
Func DegToRad($Deg)
Return (3.1415926535897932384/180)*$Deg
EndFunc
und zwar ergibt der sinus (sin) vom winkel die neue y koordinate. das bedeutet, je näher der winkel zu 0 ist, desto näher ist der sinus an den wert 1.
und der kosinus (cos) vom winkel die x koordinate. das heisst je näher der winkel an 90 ist, desto näher ist der kosinus davon an 1.
im vorgegebenen beispiel ist da noch die distanz. und zwar wissen wir erstmal wie weit wir bei diesem winkel in richtung +y laufen würden, wenn wir um eine einheit (pixel, zentimeter, meter e.t.c.) laufen würden. und das multiplizieren wir mit der distanz, da wir ja zum beispiel nicht immer einen zentimeter bei jedem schritt in eine richtung laufen, sondern immer eine andere anzahl an zentimetern pro schritt in die jeweilige richtung laufen.
Jetzt untersucht die formel und versucht diese zu verstehen.
Mathematik Sin,Cos und Ähnliches: hilfreiche Formeln
____________________________________
Da ihr den oberen Text gelesen, und den inhalt (hoffentlich) verstanden habt, können wir mit ein paar formeln anfangen.
die erste wurde schon oben genannt, möchte ich aber trotzdem noch einmal hier erwähnen (der vollständigkeit halber, und damit auch die leute die es nicht ganz verstanden haben, es besser verstehen können).
Hier nochmal das bild damit ihr die logische bedeutung der einzelnen bestandteile des codes besser erkennen könnt:
Anwendungsbeispiel:
Als nächstes kommt eine funktion mit der man die distanz zweier objekte berechnen lassen kann. mit ihr kann man beispielsweise die kollisionsbox eines kreises berechnen lassen, da man nur die entfernung zwischen der kreismitte und dem anderen punkt nehmen muss und wenn sie kleiner ist als der radius des kreises, dann ist der punkt im kreis drin.
die erste wurde schon oben genannt, möchte ich aber trotzdem noch einmal hier erwähnen (der vollständigkeit halber, und damit auch die leute die es nicht ganz verstanden haben, es besser verstehen können).
Hier nochmal das bild damit ihr die logische bedeutung der einzelnen bestandteile des codes besser erkennen könnt:
Code:
$x=100 ;die ursprüngliche x position
$y=100 ;die ursprüngliche y position
$Distanz=25 ;die distanz die "gelaufen" werden soll.
$Winkel=DegToRad(45) ;der winkel (in radianten umgewandelt, damit autoit damit arbeiten kann)
$x+=Cos($Winkel)*$Distanz ;Zu der neuen x koordinate "laufen"
$y+=Sin($Winkel)*$Distanz ;Zu der neuen y koordinate "laufen"
;Der Sinus gibt zurück wie weit man in +y richtung (zu deutsch: nach oben b.z.w. bei autoit nach unten.) "laufen" muss
;Der Cosinus (voller lateinischer name: complementi sinus) gibt zurück wie weit man in +x richtung (zu deutsch: nach rechts) "laufen" muss.
Func DegToRad($Deg) ;Die funktion zum umwandeln zu radianten (ihr könnt auch _Radian aus der Math.au3 benutzen)
Return (3.1415926535897932384/180)*$Deg
EndFunc
Code:
#include <GDIPlus.au3> ;die GDIPlus befehle laden
#include <Misc.au3>
_Gdiplus_Startup() ;Ohne _GDIPlus_Startup() funktioniert nichts
Global $hGraphics[3] ;hGraphics als eine 1Dimensionale Array mit 3 Elementen deklarieren
$WS_POPUP=0x80000000
$hGui=Guicreate("Titel",@DesktopWidth,@DesktopHeight,0,0,$WS_POPUP)
OnAutoItExitRegister("_Exit")
GUISetState()
$hGraphics[0]=_GDIPlus_GraphicsCreateFromHWND($hGui) ;Die Graphics erstellen
$hGraphics[1]=_GDIPlus_BitmapCreateFromGraphics(@DesktopWidth,@DesktopHeight,$hGraphics[0])
$hGraphics[2]=_GDIPlus_ImageGetGraphicsContext($hGraphics[1])
$x=@DesktopWidth/2 ;Startposition
$y=@DesktopHeight/2 ;Startposition
$Winkel=0 ;Startwinkel (Nach oben zeigend)
$Geschwindigkeit=0 ;Startgeschwindigkeit (Stillstehend)
While GUIGetMsg()<>-3 ;Zum beenden Esc taste drücken
If _IsPressed("57") Then $Geschwindigkeit+=1 ;Wenn ich w drücke, dann beschleunigen
If _IsPressed("53") Then $Geschwindigkeit-=2 ;Wenn ich s drücke, dann bremsen
If _IsPressed("41") Then $Winkel-=10 ;wenn ich a drücke, dann nach links lenken
If _IsPressed("44") Then $Winkel+=10 ;wenn ich d drücke, dann nach rechts lenken
$Winkel=AngleNormalize($Winkel) ;Damit der winkel nicht über 360 oder unter 0 geht
$x2=Sin(3.141592/180*$Winkel)*$Geschwindigkeit ;Berechnen wie weit er in x richtung laufen muss
$y2=Cos(3.141592/180*($Winkel-180))*$Geschwindigkeit ;-180 damit die richtung stimmt
_GDIPlus_GraphicsClear($hGraphics[2],0xFFFFFFFF) ;Den Buffer Leeren
_GDIPlus_GraphicsDrawLine($hGraphics[2],$x,$y,$x+$x2,$y+$y2) ;den "Spieler" zeichnen
_GDIPlus_GraphicsDrawImage($hGraphics[0],$hGraphics[1],0,0) ;Buffer auf Bildschirm übertragen
$x+=$x2 ;den rückgabe wert der oben genannte formel zur x position übertragen
$y+=$y2 ;den rückgabe wert der oben genannte formel zur y position übertragen
Sleep(50)
WEnd
_Exit()
Func AngleNormalize($Angle)
If $Angle>360 Then $Angle-=360
If $Angle<0 Then $Angle+=360
Return $Angle
EndFunc
Func DegToRad($Deg) ;Die funktion zum umwandeln zu radianten (ihr könnt auch _Radian aus der Math.au3 benutzen)
Return (3.1415926535897932384/180)*$Deg
EndFunc
Func _Exit() ;ist nicht wirklich nötig, kann aber gemacht werden.
_GDIPlus_GraphicsDispose($hGraphics[2])
_GDIPlus_BitmapDispose($hGraphics[1])
_GDIPlus_GraphicsDispose($hGraphics[0])
EndFunc
Als nächstes kommt eine funktion mit der man die distanz zweier objekte berechnen lassen kann. mit ihr kann man beispielsweise die kollisionsbox eines kreises berechnen lassen, da man nur die entfernung zwischen der kreismitte und dem anderen punkt nehmen muss und wenn sie kleiner ist als der radius des kreises, dann ist der punkt im kreis drin.
Code:
Func _pixellength($x1,$y1,$x2,$y2)
Return Sqrt((($x1 - $y1)^2) + (($x2 - $y2)^2))
EndFunc
Dieses Tutorial ist noch unvollständig, ich werde mich aber bemühen dieses Tutorial schnell fertig zu kriegen, und es durch regelmäßiges hochladen des aktuellen Textes immer auf dem neuesten Stand halten, es aber trotzdem so gut und einfach zu verstehen wie möglich zu gestalten.






