Sign in to follow this  
Followers 0
big_daddy

Drawing a time delayed stickman

4 posts in this topic

I've been searching for different methods to accomplish this, but so far this is all I could come up with. I'd like some suggestions, particularly on how to make the curves smoother.

#include <GUIConstants.au3>
#include <math.au3>

$maxControls = 4000
Global $controlIDs[$maxControls]
Global $nextControl = 0
$piX2 = 2 * 3.14159265358979

GUICreate("", 40, 80, @DesktopWidth / 2 - 20, @DesktopHeight / 2 - 40, $WS_POPUP)
GUISetState()

GUICtrlCreateOval(10, 10, 30, 30, 2, "0x000000")
Sleep(1000)
GUICtrlCreateLine(20, 30, 20, 60, 2, "0x000000")
Sleep(1000)
GUICtrlCreateLine(20, 60, 10, 70, 2, "0x000000")
Sleep(1000)
GUICtrlCreateLine(20, 60, 30, 70, 2, "0x000000")
Sleep(1000)
GUICtrlCreateLine(20, 40, 10, 35, 2, "0x000000")
Sleep(1000)
GUICtrlCreateLine(20, 40, 30, 35, 2, "0x000000")
Sleep(3000)


Func GUICtrlCreateLine($x1, $y1, $x2, $y2, $size = 1, $color = "0x000000")
    $deltaX = $x2 - $x1
    $deltaY = $y2 - $y1
    $length = _Ceil (Sqrt($deltaX * $deltaX + $deltaY * $deltaY))
    $incDeltaX = $deltaX / $length
    $incDeltaY = $deltaY / $length
    For $i = 0 To $length
        GUICtrlDelete($controlIDs[$nextControl])
        $controlIDs[$nextControl] = GUICtrlCreateLabel("", $x1 + $incDeltaX * $i, $y1 + $incDeltaY * $i, $size, $size)
        GUICtrlSetBkColor($controlIDs[$nextControl], $color)
        $nextControl = Mod($nextControl + 1, $maxControls)
    Next
    Return 1
EndFunc  ;==>GUICtrlCreateLine

Func GUICtrlCreateOval($x1, $y1, $x2, $y2, $size = 1, $color = "0x000000")
    $centerX = $x2 - ($x2 - $x1) / 2
    $centerY = $y2 - ($y2 - $y1) / 2
    $radiusX = Abs($centerX - $x1)
    $radiusY = Abs($centerY - $y1)
    $px = $centerX + Cos(0) * $radiusX
    $py = $centerY + Sin(0) * $radiusY
    $deltaTheta = $piX2 / $radiusX; This needs to be better thought through
    For $theta = $deltaTheta To $piX2 + $deltaTheta Step $deltaTheta
        $nx = $centerX + Cos($theta) * $radiusX
        $ny = $centerY + Sin($theta) * $radiusY
        If Not GUICtrlCreateLine($px, $py, $nx, $ny, $size, $color) Then Return 0
        $px = $nx
        $py = $ny
    Next
    Return 1
EndFunc  ;==>GUICtrlCreateOval

Thanks,

Bob

Share this post


Link to post
Share on other sites



Thanks for the suggestion, just didn't have time to decipher your code.

Could this be optimized?

#include <GUIConstants.au3>

Global $Graphic, $Timer, $TimerDiff, $Parts = 1

$GUI = GUICreate("Stickman", 600, 400, @DesktopWidth / 2 - 300, @DesktopHeight / 2 - 200)
$Graphic = GUICtrlCreateGraphic(275, 150, 50, 100)
GUICtrlSetGraphic(-1, $GUI_GR_PENSIZE, 2)
GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0)

GUISetState()

While 1
    If GUIGetMsg() = $GUI_EVENT_CLOSE Then Exit
    _CreateStickMan()
    Sleep(10)
WEnd

Func _CreateStickMan()
    $CurTime = _GetTime()
    Select
        Case $CurTime >= 1 And $Parts = 1
            GUICtrlSetGraphic($Graphic, $GUI_GR_ELLIPSE, 10, 10, 30, 30)
            GUICtrlSetGraphic($Graphic, $GUI_GR_REFRESH)
            $Parts = 2
        Case $CurTime >= 2 And $Parts = 2
            GUICtrlSetGraphic($Graphic, $GUI_GR_MOVE, 25, 40)
            GUICtrlSetGraphic($Graphic, $GUI_GR_LINE, 25, 70)
            GUICtrlSetGraphic($Graphic, $GUI_GR_REFRESH)
            $Parts = 3
        Case $CurTime >= 3 And $Parts = 3
            GUICtrlSetGraphic($Graphic, $GUI_GR_LINE, 10, 90)
            GUICtrlSetGraphic($Graphic, $GUI_GR_REFRESH)
            $Parts = 4
        Case $CurTime >= 4 And $Parts = 4
            GUICtrlSetGraphic($Graphic, $GUI_GR_MOVE, 25, 70)
            GUICtrlSetGraphic($Graphic, $GUI_GR_LINE, 40, 90)
            GUICtrlSetGraphic($Graphic, $GUI_GR_REFRESH)
            $Parts = 5
        Case $CurTime >= 5 And $Parts = 5
            GUICtrlSetGraphic($Graphic, $GUI_GR_MOVE, 25, 55)
            GUICtrlSetGraphic($Graphic, $GUI_GR_LINE, 10, 45)
            GUICtrlSetGraphic($Graphic, $GUI_GR_REFRESH)
            $Parts = 6
        Case $CurTime >= 6 And $Parts = 6
            GUICtrlSetGraphic($Graphic, $GUI_GR_MOVE, 25, 55)
            GUICtrlSetGraphic($Graphic, $GUI_GR_LINE, 40, 45)
            GUICtrlSetGraphic($Graphic, $GUI_GR_REFRESH)
            $Parts = 0
        Case Else
            If $Parts = 0 Then
                GUICtrlDelete($Graphic)
                $Graphic = GUICtrlCreateGraphic(275, 150, 50, 100)
                GUICtrlSetGraphic(-1, $GUI_GR_PENSIZE, 2)
                GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0)
                GUICtrlSetGraphic(-1, $GUI_GR_REFRESH)
                $Timer = 0
                $Parts = 1
            EndIf
    EndSelect
EndFunc  ;==>_CreateStickMan

Func _GetTime()
    If Not $Timer Then
        $Timer = TimerInit()
    Else
        $TimerDiff = Int(TimerDiff($Timer) / 1000)
        Return $TimerDiff
    EndIf
EndFunc  ;==>_GetTime

Share this post


Link to post
Share on other sites

Thanks for the suggestion, just didn't have time to decipher your code.

Could this be optimized?

#include <GUIConstants.au3>

Global $Graphic, $Timer, $TimerDiff, $Parts = 1

$GUI = GUICreate("Stickman", 600, 400, @DesktopWidth / 2 - 300, @DesktopHeight / 2 - 200)
$Graphic = GUICtrlCreateGraphic(275, 150, 50, 100)
GUICtrlSetGraphic(-1, $GUI_GR_PENSIZE, 2)
GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0)

GUISetState()

While 1
    If GUIGetMsg() = $GUI_EVENT_CLOSE Then Exit
    _CreateStickMan()
    Sleep(10)
WEnd

Func _CreateStickMan()
    $CurTime = _GetTime()
    Select
        Case $CurTime >= 1 And $Parts = 1
            GUICtrlSetGraphic($Graphic, $GUI_GR_ELLIPSE, 10, 10, 30, 30)
            GUICtrlSetGraphic($Graphic, $GUI_GR_REFRESH)
            $Parts = 2
        Case $CurTime >= 2 And $Parts = 2
            GUICtrlSetGraphic($Graphic, $GUI_GR_MOVE, 25, 40)
            GUICtrlSetGraphic($Graphic, $GUI_GR_LINE, 25, 70)
            GUICtrlSetGraphic($Graphic, $GUI_GR_REFRESH)
            $Parts = 3
        Case $CurTime >= 3 And $Parts = 3
            GUICtrlSetGraphic($Graphic, $GUI_GR_LINE, 10, 90)
            GUICtrlSetGraphic($Graphic, $GUI_GR_REFRESH)
            $Parts = 4
        Case $CurTime >= 4 And $Parts = 4
            GUICtrlSetGraphic($Graphic, $GUI_GR_MOVE, 25, 70)
            GUICtrlSetGraphic($Graphic, $GUI_GR_LINE, 40, 90)
            GUICtrlSetGraphic($Graphic, $GUI_GR_REFRESH)
            $Parts = 5
        Case $CurTime >= 5 And $Parts = 5
            GUICtrlSetGraphic($Graphic, $GUI_GR_MOVE, 25, 55)
            GUICtrlSetGraphic($Graphic, $GUI_GR_LINE, 10, 45)
            GUICtrlSetGraphic($Graphic, $GUI_GR_REFRESH)
            $Parts = 6
        Case $CurTime >= 6 And $Parts = 6
            GUICtrlSetGraphic($Graphic, $GUI_GR_MOVE, 25, 55)
            GUICtrlSetGraphic($Graphic, $GUI_GR_LINE, 40, 45)
            GUICtrlSetGraphic($Graphic, $GUI_GR_REFRESH)
            $Parts = 0
        Case Else
            If $Parts = 0 Then
                GUICtrlDelete($Graphic)
                $Graphic = GUICtrlCreateGraphic(275, 150, 50, 100)
                GUICtrlSetGraphic(-1, $GUI_GR_PENSIZE, 2)
                GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0)
                GUICtrlSetGraphic(-1, $GUI_GR_REFRESH)
                $Timer = 0
                $Parts = 1
            EndIf
    EndSelect
EndFunc ;==>_CreateStickMan

Func _GetTime()
    If Not $Timer Then
        $Timer = TimerInit()
    Else
        $TimerDiff = Int(TimerDiff($Timer) / 1000)
        Return $TimerDiff
    EndIf
EndFunc ;==>_GetTime
What are you trying to acheive with this?, a hangman game?, you want do some sort of animation?

Heres a simplifed routine to draw a circle

#include <GUIConstants.au3>
#include <Math.au3>

; == GUI generated with Koda ==);
$Graphics = GUICreate("Graphics", 592, 573, 192, 125, Bitor($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_SYSMENU,$WS_EX_TOPMOST))

$Prev = GUICtrlCreateButton("<< PREVIOUS", 8, 528, 89, 33, 0)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")
$Next = GUICtrlCreateButton("NEXT >>", 496, 528, 89, 33, 0)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")

Global $gdi_dll = DllOpen ("gdi32.dll"), $user32_dll = DllOpen ("user32.dll")
$Gh = GuiCtrlCreateGraphic(-1, -1, 600,600)

$Black  = "0x000000"
$White  = "0xFFFFFF"
$Red      = "0xFF0000"
$Green  = "0x00FF00"
$Blue     = "0x0000FF"
$Yellow = "0xFFFF00"

$XOrigin = 300
$YOrigin = 280

$Size = 280
$Wid = $Size
$Hgt = $Size

Dim $PenCol[10]
$PenCol[0] = $Black
$PenCol[1] = $White
$PenCol[2] = $Red
$PenCol[3] = $Green
$PenCol[4] = $Blue
$PenCol[5] = $Yellow

;$PenColour = "0xFFFFFF"
$BackgrndPen = "0x00D8E9EC"

WinMinimizeAll ( )

GUISetState(@SW_SHOW)
$WinPos = WinGetPos($Graphics)

WinSetOnTop ( $Graphics, "", 1 )

HotKeySet("{ESC}","STOP")

; <========= Draw a Circle =========>
$XOrigin = 300
$YOrigin = 280
$Size = 200

_Circle($XOrigin,$YOrigin,$Size,$Black) 
;_Pause()
;_ClearGraphic()
;================================
While 1
$msg = GuiGetMsg()
_CheckWin($WinPos[0],$WinPos[1])
Select
    Case $msg = $Prev
;;;;

    Case $msg = $Next
        _ClearGraphic()
EndSelect

    Select
    Case $msg = $GUI_EVENT_CLOSE
            DllClose ($gdi_dll)
            DllClose ($user32_dll)
        WinMinimizeAllUndo ( )
        ExitLoop
    EndSelect
WEnd


;===================== Draw a Circle ========================

Func _Circle($OrgX,$OrgY,$Size,$Pen)
    $Stp = 10;           <<----------- Defines the smoothness of the circle ------------
        For $R = 360 to 0 step -$Stp

            $Rad = _Radian ($R)
            $X = Sin($Rad)*$Size + $OrgX
            $Y= Cos($Rad)*$Size + $OrgY

            $R1 = $R + $Stp
            $Rad1 = _Radian ($R1)
            $Px = Sin($Rad1)*$Size + $OrgX
            $Py= Cos($Rad1)*$Size + $OrgY
            ControlFocus("Graphics","","")
        ;Sleep(1)       ;Slow it down if you want
            _DrawLine ($Graphics,$X,$Y,$Px,$Py,$PenCol[$Pen]) ; Call the DLL drawing routine.
        Next
EndFunc

;===============================================================
Func _ClearGraphic()
    GUICtrlSetGraphic($Gh, $GUI_GR_REFRESH)
EndFunc

Func _Pause()
msgbox(0,"Pause","View Next Graphic?")
_ClearGraphic()
EndFunc

Func _Cont()
msgbox(0,"","Continue?")
EndFunc

Func _IncCol(ByRef $Pen)
    $Pen = $Pen + 1
    If $Pen >5 then 
        $Pen = 0
    EndIF
EndFunc

Func Stop()
    Exit
EndFunc

Func _Tog(ByRef $Pen)
    If $Pen = 0 then
        $Pen = 1
    Else
        $Pen = 0
    EndIf
EndFunc 

Func _CheckWin($WinX,$WinY)
    If $WinX <> $WinX or $WinY <> $WinY then 
        run("Rundll32 user,repaintscreen")
        $WinX = $WinPos[0]
        $WinY = $WinPos[1]
        WinMinimizeAll ( )
    EndIf
EndFunc

; ==================  DLL Drawing Routines  ======================
Func _DrawLine($GUI,$x, $y, $EndPntX, $EndPointY, $PenColour)
    $GUIHDC = DllCall ($user32_dll,"int","GetDC","hwnd", $GUI)
    $Pen = DllCall($gdi_dll, "hwnd", "CreatePen", "int", "0", "int", "0", "hwnd", $PenColour)
    $Pen = $Pen[0]
    DllCall($gdi_dll, "hwnd", "SelectObject", "hwnd", $GUIHDC[0], "hwnd", $Pen)
    DllCall ($gdi_dll, "int", "MoveToEx", "hwnd", $GUIHDC[0], "int", $x, "int", $y, "ptr", 0)
    DllCall ($gdi_dll, "int", "LineTo", "hwnd", $GUIHDC[0], "int", $EndPntX, "int", $EndPointY)
    DllCall ($user32_dll,"int","ReleaseDC","int",$GUIHDC[0],"hwnd",$GUI)
EndFunc

2015 - Still no flying cars, instead blankets with sleeves.

Share this post


Link to post
Share on other sites

Yes, it is for a hangman game I'm making. I achieved the affect I wanted with the code I posted, just wanted some suggestions on how to optimize it.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0