so wie ich das verstehe meint er eine Funktion analog zu
[autoit]controlmove()
[/autoit]
@Jautois
Der große Vorteil von GDI+ ist die einfache Darstellung von Bildern, Pixeln, Zeichnungen über fertige Funktionen.
Für Vorhaben, für die es keine fertige Funktion gibt, wie z.B. dein "Spritemove", musst du das bei GDI+ selbst in die Hand nehmen.
Das Problem für die meisten ist, daß es nur eine einzige "Leinwand" gibt, auf der alle Operationen stattfinden.
Für Deinen "Spritemove" nun die Vorgehensweise in Pseudocode:
1. Hintergrund zeichnen
Für eine "Bewegung" des Sprites ist es wichtig, den Hintergrund an der Spriteposition zu sichern! Denn der wird überschrieben, sobald du an dieser Position das Sprite zeichnest. Wenn dein Sprite sich "über" den Hintergrung bewegen soll, dann ist das eine Folge von Hintergrund zeichnen, Sprite an neuer Position zeichnen, Hintergrund zeichnen, Sprite an neuer Position zeichnen, uswusf
Das schnelle "Zeichnen" auf den Hintergrund geht wunderbar mittels BitBlt (blitten), dabei wird ein Speicherbereich (dein Sprite) an eine andere Position im Speicher (den Hintergrund) verschoben. vgl (
_WinAPI_BitBlt()
_GDIPlus_GraphicsDrawImageRectRect () ;der gdi+ "wrapper" zu bitblt
)
Beispiel aus der Hilfe ein bissl aufgepeppt und verschiedene Techniken gezeigt: Bitte mit Scite im Fullscreen ausführen (wg des AutoItlogos^^)
Spoiler anzeigen
#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
Opt('MustDeclareVars', 1)
[/autoit] [autoit][/autoit] [autoit]_Main()
[/autoit] [autoit][/autoit] [autoit]Func _Main()
Local $hGUI1, $hGUI2, $hHintergrund, $hGraphic1, $hGraphic2, $hSprite, $backbuffer, $bitmap
; Capture top left corner of the screen
_ScreenCapture_Capture(@MyDocumentsDir & "\Hintergrund.jpg", 0, 0, 800, 600) ;hintergrund erstellen
_ScreenCapture_Capture(@MyDocumentsDir & "\Sprite.jpg", 0, 0, 20, 20) ;Sprite erstellen
; Create a GUI for the original image
$hGUI1 = GUICreate("Original", 800, 600, 0, 0)
GUISetState()
; Initialize GDI+ library and load image
_GDIPlus_Startup()
$hHintergrund = _GDIPlus_ImageLoadFromFile(@MyDocumentsDir & "\Hintergrund.jpg") ;das ist der Hintergrund
$hSprite = _GDIPlus_BitmapCreateFromFile(@MyDocumentsDir & "\Sprite.jpg") ;das ist das Sprite
; Draw original image
$hGraphic1 = _GDIPlus_GraphicsCreateFromHWND($hGUI1) ;"Leinwand" erstellen auf der gemalt werden kann
_GDIPlus_GraphicsDrawImage($hGraphic1, $hHintergrund, 0, 0) ;hintergrund auf diese Leinwand malen
MsgBox(0, 0, "Hintergrund gezeichnet")
_GDIPlus_GraphicsDrawImageRectRect($hGraphic1, $hSprite, 0, 0, 20, 20, 0, 0, 40, 40) ;das sprite wird doppelt so groß
[/autoit] [autoit][/autoit] [autoit]MsgBox(0, 0, "sprite gezeichnet, es folgt die Bewegung")
[/autoit] [autoit][/autoit] [autoit]For $i = 0 To 300 Step 2
_GDIPlus_GraphicsDrawImageRectRect($hGraphic1, $hSprite, 0, 0, 20, 20, $i, $i, 40, 40)
Next
MsgBox(0, 0, "Das war gut, aber der Hintergrund wurde nicht aktualisiert, also nochmal....")
For $i = 0 To 300 Step 2
_GDIPlus_GraphicsDrawImage($hGraphic1, $hHintergrund, 0, 0) ;hintergrund auf diese Leinwand malen
_GDIPlus_GraphicsDrawImageRectRect($hGraphic1, $hSprite, 0, 0, 20, 20, $i, $i, 40, 40)
Next
MsgBox(0, 0, "wars so gut? Nein, es flackert...wir benutzen einen sog. backbuffer, dabei wird das gesamte Bild im backbuffer erstellt und dieser danach erst komplett dargestellt")
$bitmap = _GDIPlus_BitmapCreateFromGraphics(800, 600, $hGraphic1) ;Objekt erstellen
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap) ;backbuffer erstellen, eine 2. Leinwand im Hintergrund sozusagen
For $i = 0 To 300 Step 2
_GDIPlus_GraphicsDrawImage($backbuffer, $hHintergrund, 0, 0) ;hintergrund in den backbuffer malen
; _GDIPlus_GraphicsDrawImage($backbuffer, $hsprite, $i, $i) ;Sprite in den backbuffer malen
_GDIPlus_GraphicsDrawImageRectRect($backbuffer, $hSprite, 0, 0, 20, 20, $i, $i, 40, 40)
_GDIPlus_GraphicsDrawImageRect($hGraphic1, $bitmap, 0, 0, 800, 600);gesamten backbuffer darstellen
Next
MsgBox(0, 0, "wars so gut? ja, so soll es sein ;-)")
; Release resources
_GDIPlus_GraphicsDispose($hGraphic1)
_GDIPlus_GraphicsDispose($backbuffer)
_GDIPlus_ImageDispose($hHintergrund)
_GDIPlus_Shutdown()
; Clean up screen shot file
FileDelete(@MyDocumentsDir & "\Hintergrund.jpg")
FileDelete(@MyDocumentsDir & "\sprite.jpg")
; Loop until user exits
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc ;==>_Main
[/autoit]/edit/ richtig schnell wird es, wenn so wenig Daten wie möglich bewegt werden müssen. Dazu wäre es sinnvoll, nicht den gesamten Hintergrund neu zu zeichnen, sondern nur das kleine Stück, welches vom "aktuellen" Sprite verdeckt wird