mühle gdi+ problem

  • Hallo zusammen:

    Ich habe mir vorgenommen ein Mühle-Spiel zu proggen... Die Idee ist, dass man, wenn man über eine mögliche Ablageposition hovert ein Stein dort erscheint und wieder weggeht, sobald man die maus wieder wegbegt. Sobald man aber klickt soll der Stein dort fest installiert bleiben und sich die Farbe wechseln. An diesm Punkt haperts noch etwas.
    Das Problem ist das das Fenster mit _WinAPI_RedrawWindow() das Fenster aktualisiert sobaldman mit der Maus wieder weghovert.(Ich habe keine Möglichkeit gefunden ein einzelnes GDI+ Objekt zu löschen, ohne dabei die ganze Graphic zu löschen.) Das Problem ist halt, dass alles so funktionieren soll nachdem ein Stein "fest installiert" ist. Hierbei aktualisiert er aber auch immer und daher geht der Stein den man gelegt hat immer wieder weg.
    Mein Ansatz war anstatt von_WinAPI_RedrawWindow() einfach nach jedem Ablegen eines Steins eine neue GDI+ Graphic zu erstellen und die alte mittels _GDIPlus_GraphicsClear Transparent zu machen, sobald man weghovert. Sobald ein Stein gelegt wurde, wird die Grafik dann einfach nicht transparent gemacht. Hierbei wird aber komischerweise wieder der ganze Bildschirm schwarz anstatt die Grafik transparent und die Gui weiterhin sichtbar ;)
    Ich hoffe jemand versteht überhaupt das Problem^^
    Vielen Dank im Voraus.
    RapIT

  • n mühle spiel hat hier grade mal jmd gemacht (mir fällt der name grad nich ein :D )
    zu deinem problem
    warum willst du das ganze nur neu zeichnen wen sich etwas geändert hat
    setz das zeichnen in ne while und prüf immer ob der curser auf so ner position is
    kannst mich mal in skype adden (falls dus hast) dan helf erklär ichs dir genauer :D

  • Du musst die Positionen der Steine in einem Array speichern und bei jedem Zeichenvorgang dann die Steine an den gespeicherten Stellen zeichnen. Ein Zeichenvorgang sieht dann etwa so aus:
    - Zwischenspeicher löschen
    - Hintergrund zeichen
    - gespeicherte Steine zeichnen
    - Mausposition abfragen und bei erlaubter Position Stein zeichen
    - Zwischenspeicher auf Bildschirm übertragen
    - nächster Zeichenvorgang

    PS: Das nennt sich Doppelpuffer

  • Ich hbe auch ein Beispiel für dich ;) Ein Mausklick schaltet einen Kreis an, der nächste wieder aus.

    Spoiler anzeigen
    [autoit]

    #include<GDIplus.au3>
    #include<WindowsConstants.au3>
    #include<GUIConstantsEx.au3>
    Global $hBmpBuffer, $hGraphicsBuffer, $hGraphics, $hGUI, $fClick=False, $fShow
    _GDIPlus_Startup()
    OnAutoItExitRegister("_FreeResources")
    Global Const $iWidth = 800, $iHeight = 600
    Opt("GUIOnEventMode", 1)

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

    $hGUI = GUICreate("test", $iWidth, $iHeight)
    $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    $hBmpBuffer = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
    $hGraphicsBuffer = _GDIPlus_ImageGetGraphicsContext($hBmpBuffer)
    _GDIPlus_GraphicsClear($hGraphicsBuffer, 0xFFFFFFFF)

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

    GUIRegisterMsg($WM_PAINT, "_MY_PAINT")
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    GUISetState()

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

    While 1
    Sleep(20)
    $info = GUIGetCursorInfo("")
    If @error Then ContinueLoop

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

    If _MouseDownEvent($info[2]) Then
    $fClick = Not $fClick
    _GDIPlus_GraphicsClear($hGraphicsBuffer, 0xFFFFFFFF)
    Switch $fClick
    Case True
    _GDIPlus_GraphicsFillEllipse($hGraphicsBuffer, $info[0]-20, $info[1]-20, 40, 40)
    EndSwitch
    _WinAPI_RedrawWindow($hGUI, 0, 0, $RDW_INTERNALPAINT)
    EndIf
    WEnd

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

    Func _MouseDownEvent($iPressed)
    ; Author: ProgAndy
    Local Static $iState=False
    Local $fRet = False
    If Not $iState And $iPressed Then $fRet=True
    $iState = $iPressed
    Return $fRet
    EndFunc

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

    Func _Exit()
    Exit
    EndFunc

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

    Func _MY_PAINT($hWnd, $uMsg, $lParam, $wParam)
    If $hGUI = $hWnd Then _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBmpBuffer, 0, 0, $iWidth, $iHeight)
    Return $GUI_RUNDEFMSG
    EndFunc

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

    Func _FreeResources()
    GUIRegisterMsg($WM_PAINT, "")
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_GraphicsDispose($hGraphicsBuffer)
    _GDIPlus_BitmapDispose($hBmpBuffer)
    _GDIPlus_Shutdown()
    EndFunc

    [/autoit]
  • Das Mühle Spiel, das yxyx erwähnt hat, war von mir :D
    Werd morgen eine neue Version mit Optionen und Menü und weiteren lustigen Animationen beim Bewegen posten ;)

    Spoiler anzeigen

    Grundkenntnisse in: C++, JavaScript
    Sehr gute Kenntnisse: PHP, JAVA, C und näturlich AutoIt


    Klaviatur, Anhang UDF, GDI+ Mühle

    Zitat

    "Wenn einen um 20h der Pizzadienst anruft und fragt, ob man's nur vergessen hat und ob man das gleiche
    möchte wie immer -- dann sollte man sein Bestellverhalten evtl überdenken"

  • Aber im Programm verwendest du doch dies _GDIPlus_GraphicsClear($hGraphicsBuffer, 0xFFFFFFFF) und das kann ich bei mir ja nicht, weil dann auch die gui dahinter kaputt geht... Aber ich glaube ich weiß wie ich es machen muss...


    Deshalb gibt es ja den Doppelpuffer.
    Dieser wird komplett gelöscht, komplett neu gezeichent und dann in einem Rutsch auf die GUI übertragen. Dadurch flackert es auch kaum, weil das Zeichnen nicht nach und nach auf dem Bildschirm geschieht.
    Kleines Beispiel:

    Spoiler anzeigen
    [autoit]

    #include<GDIplus.au3>
    #include<WindowsConstants.au3>
    #include<GUIConstantsEx.au3>
    Global $hBmpBuffer, $hGraphicsBuffer, $hGraphics, $hGUI, $fClick=False, $fShow, $aMousePos[2]
    _GDIPlus_Startup()
    OnAutoItExitRegister("_FreeResources")
    Global Const $iWidth = 600, $iHeight = 600
    Opt("GUIOnEventMode", 1)

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

    $hGUI = GUICreate("test", $iWidth, $iHeight)
    $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    $hBmpBuffer = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
    $hGraphicsBuffer = _GDIPlus_ImageGetGraphicsContext($hBmpBuffer)
    _GDIPlus_GraphicsClear($hGraphicsBuffer, 0xFFFFFFFF)

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

    GUIRegisterMsg($WM_PAINT, "_MY_PAINT")
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    GUISetState()

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

    While 1
    Sleep(20)
    $info = GUIGetCursorInfo("")
    If @error Then ContinueLoop

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

    If _MouseDownEvent($info[2]) Then
    $fClick = Not $fClick
    Global $aMousePos[2] = [$info[0], $info[1]]
    EndIf

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

    ; Zeichenvorgang

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

    _GDIPlus_GraphicsClear($hGraphicsBuffer, 0xFFFFFFFF)

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

    _GDIPlus_GraphicsDrawRect($hGraphicsBuffer, 10, 10, 580, 580)
    _GDIPlus_GraphicsDrawRect($hGraphicsBuffer, 100, 100, 400, 400)
    _GDIPlus_GraphicsDrawRect($hGraphicsBuffer, 190, 190, 220, 220)
    _GDIPlus_GraphicsDrawLine($hGraphicsBuffer, 10, 300, 190, 300)
    _GDIPlus_GraphicsDrawLine($hGraphicsBuffer, 590, 300, 410, 300)
    _GDIPlus_GraphicsDrawLine($hGraphicsBuffer, 300, 10, 300, 190)
    _GDIPlus_GraphicsDrawLine($hGraphicsBuffer, 300, 590, 300, 410)

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

    If $fClick Then _GDIPlus_GraphicsFillEllipse($hGraphicsBuffer, $aMousePos[0]-20, $aMousePos[1]-20, 40, 40)

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

    _WinAPI_RedrawWindow($hGUI, 0, 0, $RDW_INTERNALPAINT)

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

    WEnd

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

    Func _MouseDownEvent($iPressed)
    ; Author: ProgAndy
    Local Static $iState=False
    Local $fRet = False
    If Not $iState And $iPressed Then $fRet=True
    $iState = $iPressed
    Return $fRet
    EndFunc

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

    Func _Exit()
    Exit
    EndFunc

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

    Func _MY_PAINT($hWnd, $uMsg, $lParam, $wParam)
    If $hGUI = $hWnd Then _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBmpBuffer, 0, 0, $iWidth, $iHeight)
    Return $GUI_RUNDEFMSG
    EndFunc

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

    Func _FreeResources()
    GUIRegisterMsg($WM_PAINT, "")
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_GraphicsDispose($hGraphicsBuffer)
    _GDIPlus_BitmapDispose($hBmpBuffer)
    _GDIPlus_Shutdown()
    EndFunc

    [/autoit]

    2 Mal editiert, zuletzt von progandy (6. Juli 2010 um 08:02)