Jump to content

Drawing a time delayed stickman


Recommended Posts

  • Moderators

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

Link to comment
Share on other sites

  • Moderators

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
Link to comment
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.

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...