Jump to content
Sign in to follow this  
strongy

Drawing Archery target with clickable zones

Recommended Posts

Greetings, I'm trying to figure out the simplest way to draw an Archery target so that I can click on the color's to add the scores up.

I have looked at using _GDIPlus, but this seems quite complicated. Is there any easier way? 

Looking for suggestions, and certainly not asking anyone to write it for me.

ft-60cm.jpg

Share this post


Link to post
Share on other sites

So, I think I have the target up and running. Struggling to get the hit locations working now though.. 

Here's where I am..

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <Math.au3>

Opt("MouseCoordMode", 2) ;1=absolute, 0=relative, 2=client

Target()

Func Target()
    _GDIPlus_Startup() ;initialize GDI+
    Local Const $iWidth = 1000, $iHeight = 1000, $iBgColor = 0x000000 ;$iBGColor format RRGGBB

    Local $hGUI = GUICreate("GDI+ Example (" & @ScriptName & ")", $iWidth, $iHeight) ;create a test GUI
    GUISetBkColor($iBgColor, $hGUI) ;set GUI background color
    GUISetState(@SW_SHOW)

    Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;create a graphics object from a window handle
    _GDIPlus_GraphicsSetSmoothingMode($hGraphics, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ;sets the graphics object rendering quality (antialiasing)
    Local $hPen

    _GDIPlus_GraphicsDrawArc($hGraphics, 30, 30, 563, 563, 270, 360, _GDIPlus_PenCreate(0xFFFFFFFF, 32)) ; White
    _GDIPlus_GraphicsDrawArc($hGraphics, 62, 62, 500, 500, 270, 360, _GDIPlus_PenCreate(0xFFFFFFFF, 32)) ; White
    _GDIPlus_GraphicsDrawArc($hGraphics, 94, 94, 436, 436, 270, 360, _GDIPlus_PenCreate(0xFF000000, 32)) ; Black
    _GDIPlus_GraphicsDrawArc($hGraphics, 125, 125, 373, 373, 270, 360, _GDIPlus_PenCreate(0xFF000000, 32)) ; Black
    _GDIPlus_GraphicsDrawArc($hGraphics, 156, 156, 310, 310, 270, 360, _GDIPlus_PenCreate(0xFF3333FF, 32)) ; Blue
    _GDIPlus_GraphicsDrawArc($hGraphics, 188, 188, 247, 247, 270, 360, _GDIPlus_PenCreate(0xFF3333FF, 32)) ; Blue
    _GDIPlus_GraphicsDrawArc($hGraphics, 220, 220, 183, 183, 270, 360, _GDIPlus_PenCreate(0xFFFF3333, 32)) ; Red
    _GDIPlus_GraphicsDrawArc($hGraphics, 252, 252, 120, 120, 270, 360, _GDIPlus_PenCreate(0xFFFF3333, 32)) ; Red
    _GDIPlus_GraphicsDrawArc($hGraphics, 284, 284, 57, 57, 270, 360, _GDIPlus_PenCreate(0xFFFFFF00, 32)) ; Yellow
    _GDIPlus_GraphicsFillEllipse($hGraphics, 300, 300, 25, 25, _GDIPlus_BrushCreateSolid(0xFFFFFF00)) ; Yellow

    _GDIPlus_GraphicsDrawArc($hGraphics, 12, 12, 597, 597, 270, 360, _GDIPlus_PenCreate(0xFF000000, 2)) ; LINE
    _GDIPlus_GraphicsDrawArc($hGraphics, 45, 45, 533, 533, 270, 360, _GDIPlus_PenCreate(0xFF000000, 2)) ; LINE
    _GDIPlus_GraphicsDrawArc($hGraphics, 77, 77, 470, 470, 270, 360, _GDIPlus_PenCreate(0xFFFFFFFF, 2)) ; LINE
    _GDIPlus_GraphicsDrawArc($hGraphics, 109, 109, 407, 407, 270, 360, _GDIPlus_PenCreate(0xFFFFFFFF, 2)) ; LINE
    _GDIPlus_GraphicsDrawArc($hGraphics, 141, 141, 344, 344, 270, 360, _GDIPlus_PenCreate(0xFF000000, 2)) ; LINE
    _GDIPlus_GraphicsDrawArc($hGraphics, 173, 173, 281, 281, 270, 360, _GDIPlus_PenCreate(0xFF000000, 2)) ; LINE
    _GDIPlus_GraphicsDrawArc($hGraphics, 205, 205, 215, 215, 270, 360, _GDIPlus_PenCreate(0xFF000000, 2)) ; LINE
    _GDIPlus_GraphicsDrawArc($hGraphics, 237, 237, 155, 155, 270, 360, _GDIPlus_PenCreate(0xFF000000, 2)) ; LINE
    _GDIPlus_GraphicsDrawArc($hGraphics, 268, 268, 90, 90, 270, 360, _GDIPlus_PenCreate(0xFF000000, 2)) ; LINE
    _GDIPlus_GraphicsDrawArc($hGraphics, 301, 301, 25, 25, 270, 360, _GDIPlus_PenCreate(0xFF000000, 2)) ; LINE

    _GDIPlus_GraphicsDrawString($hGraphics, "1", 25, 305)
    _GDIPlus_GraphicsDrawString($hGraphics, "2", 57, 305)
    _GDIPlus_GraphicsDrawString($hGraphics, "3", 89, 305)
    _GDIPlus_GraphicsDrawString($hGraphics, "4", 120, 305)
    _GDIPlus_GraphicsDrawString($hGraphics, "5", 151, 305)
    _GDIPlus_GraphicsDrawString($hGraphics, "6", 183, 305)
    _GDIPlus_GraphicsDrawString($hGraphics, "7", 215, 305)
    _GDIPlus_GraphicsDrawString($hGraphics, "8", 247, 305)
    _GDIPlus_GraphicsDrawString($hGraphics, "9", 279, 305)
    _GDIPlus_GraphicsDrawString($hGraphics, "10", 304, 305)

    While 1
        $msg = GUIGetMsg()
        Switch $msg
            Case $GUI_EVENT_CLOSE
                Exit

            Case $GUI_EVENT_MOUSEMOVE
                $aPos = MouseGetPos()
                ToolTip("Mouse Position X:  " & $aPos[0] & "   Y: " & $aPos[1])
        EndSwitch
    WEnd

EndFunc   ;==>Target

 

Share this post


Link to post
Share on other sites
Local $hPen2 = _GDIPlus_PenCreate(0xFF00FF00, 3, 2)

    While 1
        $msg = GUIGetMsg()
        Switch $msg
            Case $GUI_EVENT_CLOSE
                Exit
            Case $GUI_EVENT_MOUSEMOVE
                $aPos = MouseGetPos()
                ToolTip("Mouse Position X:  " & $aPos[0] & "   Y: " & $aPos[1])
            Case $GUI_EVENT_PRIMARYDOWN
                ConsoleWrite('_GDIPlus_GraphicsDrawPie '&@MSEC&@CRLF)
                _GDIPlus_GraphicsDrawEllipse($hGraphics, $aPos[0] - 9, $aPos[1] - 9, 16, 16, $hPen2)
        EndSwitch
    WEnd

 


Spoiler

Renamer - Rename files and folders, remove portions of text from the filename etc.

GPO Tool - Export/Import Group policy settings.

MirrorDir - Synchronize/Backup/Mirror Folders

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

String Trigger - Triggers pasting text or applications or internet links on specific strings.

Inconspicuous - Hide files in plain sight, not fully encrypted.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

IUIAutomation - Topic with framework and examples

Au3Record.exe

Share this post


Link to post
Share on other sites

You can do something like this here.

;coded by UEZ build 2017-12-21
#include <GDIPlus.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>

_GDIPlus_Startup()
Global $hGUI, $iFPS = 0, $iShowFPS = 0, $bExit
Global Const $iW = 1000, $iH = 800, $iWh = $iW / 2, $iHh = $iH / 2, $sTitle = "GDI+ Archery Board"

AutoItSetOption("GUIOnEventMode", 1)

GDIPlus_Archeryboard()

AutoItSetOption("GUIOnEventMode", 0)
_GDIPlus_Shutdown()


Func GDIPlus_Archeryboard()
    $bExit = False
    $hGUI = GUICreate($sTitle, $iW, $iH) ;, 0, 0, $WS_POPUP)
    GUISetState(@SW_SHOW, $hGUI)
;~  GUISetCursor(16, 1)

    ;create canvas elements
    Local Const $hDC = _WinAPI_GetDC($hGUI)
    Local Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH)
    Local Const $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC)
    Local Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hHBitmap)
    Local Const $hCanvas = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer)
    _GDIPlus_GraphicsSetSmoothingMode($hCanvas, $GDIP_SMOOTHINGMODE_HIGHQUALITY)
    _GDIPlus_GraphicsSetPixelOffsetMode($hCanvas, $GDIP_PIXELOFFSETMODE_HIGHQUALITY)

    Local Const $hBrush_Clr = _GDIPlus_BrushCreateSolid(0xFFC0C0C0), _
                $hBrush_FPS = _GDIPlus_BrushCreateSolid(0xF0404040), _
                $hFormat_FPS = _GDIPlus_StringFormatCreate(), _
                $hFamily_FPS = _GDIPlus_FontFamilyCreate("Arial"), _
                $hFont_FPS = _GDIPlus_FontCreate($hFamily_FPS, 8), _
                $tLayout_FPS = _GDIPlus_RectFCreate(0, 0, 60, 16)

    $iFPS = 0
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit_About")
    AdlibRegister("CalcFPS", 1000)

    Local Const $fRadius = 39.5
    Local $hBitmap_AB = BitmapCreate_Archeryboard($iW, $iH, $fRadius)

    Local $i, $sInfo, $aPos, $fDist, $iRing

    Do
        DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush_Clr, "float", 0, "float", 0, _
                "float", $iW, "float", $iH) ;erase canvas background

        _GDIPlus_GraphicsDrawImageRect($hCanvas, $hBitmap_AB, 0, 0, $iW, $iH)

        ;check for mouse cursor
        $aPos  = GUIGetCursorInfo($hGUI)
        $fDist = Pixel_Distance($aPos[0], $aPos[1], $iWh, $iHh) ;get distance to center
        If (10 * $fRadius - $fDist) > 0.0 Then ;check if mouse is on archery board
            $iRing = Mod(Int($fDist / $fRadius), $fRadius) ;get actual ring
            Switch $iRing
                Case 0
                    $sInfo = "10 points, yellow / center"
                Case 1
                    $sInfo = "9 points, yellow"
                Case 2
                    $sInfo = "8 points, red 1"
                Case 3
                    $sInfo = "7 points, red 2"
                Case 4
                    $sInfo = "6 points, blue 1"
                Case 5
                    $sInfo = "5 points, blue 2"
                Case 6
                    $sInfo = "4 points, grey 1"
                Case 7
                    $sInfo = "3 points, grey 2"
                Case 8
                    $sInfo = "2 points, white 1"
                Case 9
                    $sInfo = "1 points, white 2"
            EndSwitch
        Else
            $sInfo = "Not on board"
        EndIf

        _GDIPlus_GraphicsDrawStringEx($hCanvas, "FPS: " & $iShowFPS, $hFont_FPS, $tLayout_FPS, $hFormat_FPS, $hBrush_FPS) ;draw fps
        _WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hDC_backbuffer, 0, 0, $SRCCOPY) ;blit drawn bitmap to GUI

        ToolTip($sInfo, MouseGetPos(0), MouseGetPos(1) + 20)

        $iFPS += 1
        If $bExit Then ExitLoop
    Until Not Sleep(30)

    AdlibUnRegister("CalcFPS")

    ;release resources
    _GDIPlus_FontDispose($hFont_FPS)
    _GDIPlus_FontFamilyDispose($hFamily_FPS)
    _GDIPlus_StringFormatDispose($hFormat_FPS)
    _GDIPlus_BrushDispose($hBrush_Clr)
    _GDIPlus_BrushDispose($hBrush_FPS)
    _GDIPlus_GraphicsDispose($hCanvas)
    _WinAPI_SelectObject($hDC_backbuffer, $DC_obj)
    _WinAPI_DeleteDC($hDC_backbuffer)
    _WinAPI_DeleteObject($hHBitmap)
    _WinAPI_ReleaseDC($hGUI, $hDC)
    GUIDelete($hGUI)
EndFunc   ;==>GDIPlus_Archeryboard

Func BitmapCreate_Archeryboard($iW, $iH, $fRadius)
    Local Const $fDiameter = 2 * $fRadius, $iWh = $iW / 2, $iHh = $iH / 2
    Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH), $hCanvas = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetSmoothingMode($hCanvas, $GDIP_SMOOTHINGMODE_HIGHQUALITY)
    _GDIPlus_GraphicsSetPixelOffsetMode($hCanvas, $GDIP_PIXELOFFSETMODE_HIGHQUALITY)
    Local Const $hBrush1 = _GDIPlus_BrushCreateSolid(0xFFFFFF55), _      ;yellow
                $hPen7 = _GDIPlus_PenCreate(0x70FFFFFF), _               ;white with default width
                $hPen6 = _GDIPlus_PenCreate(0x50505050), _               ;grey
                $hPen5 = _GDIPlus_PenCreate(0x50202020), _               ;dark grey
                $hPen4 = _GDIPlus_PenCreate(0xFFFF5443, 2 * $fRadius), _ ;red
                $hPen3 = _GDIPlus_PenCreate(0xFF66C5FF, 2 * $fRadius), _ ;blue
                $hPen2 = _GDIPlus_PenCreate(0xFF47433F, 2 * $fRadius), _ ;grey
                $hPen1 = _GDIPlus_PenCreate(0xFFFEFEFE, 2 * $fRadius), _ ;white
                $hPath1 = _GDIPlus_PathCreate(), $hPath2 = _GDIPlus_PathCreate(), _
                $hPath3 = _GDIPlus_PathCreate(), $hPath4 = _GDIPlus_PathCreate(), _
                $hPath5 = _GDIPlus_PathCreate()

    _GDIPlus_PathAddArc($hPath1, $iWh - 9 * $fRadius, $iHh - 9 * $fRadius, 18 * $fRadius, 18 * $fRadius, 0, 360)
    _GDIPlus_PathAddArc($hPath2, $iWh - 7 * $fRadius, $iHh - 7 * $fRadius, 14 * $fRadius, 14 * $fRadius, 0, 360)
    _GDIPlus_PathAddArc($hPath3, $iWh - 5 * $fRadius, $iHh - 5 * $fRadius, 10 * $fRadius, 10 * $fRadius, 0, 360)
    _GDIPlus_PathAddArc($hPath4, $iWh - 3 * $fRadius, $iHh - 3 * $fRadius, 6 * $fRadius, 6 * $fRadius, 0, 360)
    _GDIPlus_PathAddEllipse($hPath5, $iWh - 2 * $fRadius, $iHh - 2 * $fRadius, 4 * $fRadius, 4 * $fRadius)

    ;draw board with different colors
    _GDIPlus_GraphicsDrawPath($hCanvas, $hPath1, $hPen1)
    _GDIPlus_GraphicsDrawPath($hCanvas, $hPath2, $hPen2)
    _GDIPlus_GraphicsDrawPath($hCanvas, $hPath3, $hPen3)
    _GDIPlus_GraphicsDrawPath($hCanvas, $hPath4, $hPen4)
    _GDIPlus_GraphicsFillPath($hCanvas, $hPath5, $hBrush1)

    ;draw boarders
    For $i = 1 to 10
        Switch $i
            Case 7
                _GDIPlus_GraphicsDrawEllipse($hCanvas, $iWh - $i * $fRadius, $iHh - $i * $fRadius, $i * $fDiameter, $i * $fDiameter, $hPen7)
            Case Else
                _GDIPlus_GraphicsDrawEllipse($hCanvas, $iWh - $i * $fRadius, $iHh - $i * $fRadius, $i * $fDiameter, $i * $fDiameter, $hPen5)
        EndSwitch
    Next
    _GDIPlus_GraphicsDrawEllipse($hCanvas, $iWh - 0.5 * $fRadius, $iHh - 0.5 * $fRadius, $fRadius, $fRadius, $hPen6)

    ;draw cross-hair
    _GDIPlus_GraphicsDrawLine($hCanvas, $iWh, $iHh - 4, $iWh, $iHh + 4, $hPen6)
    _GDIPlus_GraphicsDrawLine($hCanvas, $iWh - 4, $iHh, $iWh + 4, $iHh, $hPen6)

    ;clean-up resources
    _GDIPlus_PathDispose($hPath1)
    _GDIPlus_PathDispose($hPath2)
    _GDIPlus_PathDispose($hPath3)
    _GDIPlus_PathDispose($hPath4)
    _GDIPlus_PathDispose($hPath5)
    _GDIPlus_PenDispose($hPen1)
    _GDIPlus_PenDispose($hPen2)
    _GDIPlus_PenDispose($hPen3)
    _GDIPlus_PenDispose($hPen4)
    _GDIPlus_PenDispose($hPen5)
    _GDIPlus_PenDispose($hPen6)
    _GDIPlus_PenDispose($hPen7)
    _GDIPlus_BrushDispose($hBrush1)
    _GDIPlus_GraphicsDispose($hCanvas)

    Return $hBitmap
EndFunc

Func Pixel_Distance($x1, $y1, $x2, $y2) ;Pythagoras theorem
    Local $a, $b
    If $x2 = $x1 And $y2 = $y1 Then Return 0
    $a = $y2 - $y1
    $b = $x2 - $x1
    Return Sqrt($a * $a + $b * $b)
EndFunc   ;==>Pixel_Distance


Func _Exit_About()
    $bExit = True
EndFunc   ;==>_Exit_About

Func CalcFPS() ;display FPS
    $iShowFPS = $iFPS
    $iFPS = 0
EndFunc   ;==>CalcFPS

I used the path functions which is not necessary because I wanted to use _GDIPlus_PathIsVisiblePoint to check the cursor position but forgot that it will work only for real filled areas!

Edited by UEZ
Another code update :-)

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

Here i was thinking the OP meant he needed to mark the hits, but looking at your example i see he could have meant, a points system dependant on the area of the hit.


Spoiler

Renamer - Rename files and folders, remove portions of text from the filename etc.

GPO Tool - Export/Import Group policy settings.

MirrorDir - Synchronize/Backup/Mirror Folders

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

String Trigger - Triggers pasting text or applications or internet links on specific strings.

Inconspicuous - Hide files in plain sight, not fully encrypted.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

IUIAutomation - Topic with framework and examples

Au3Record.exe

Share this post


Link to post
Share on other sites

Thank you UEZ! I was working on doing the same..

Your method was much cleaner than mine, :D

Switch Pixel_Distance($aPos[0], $aPos[1], $iWh, $iHh) ;get distance from mouse cursor from board center
            Case 0 To (1 * $fRadius)
                $sInfo = "Yellow 10"
            Case 1 To (2 * $fRadius)
                $sInfo = "Yellow 9"
            Case (2 * $fRadius) + 0.1 To 1.5 * (2 * $fRadius)
                $sInfo = "Red 8"
            Case 1.5 * (2 * $fRadius) + 0.1 To 2 * (2 * $fRadius)
                $sInfo = "Red 7"
            Case 2 * (2 * $fRadius) + 0.1 To 2.5 * (2 * $fRadius)
                $sInfo = "Blue 6"
            Case 2.5 * (2 * $fRadius) + 0.1 To 3 * (2 * $fRadius)
                $sInfo = "Blue 5"
            Case 3 * (2 * $fRadius) + 0.1 To 3.5 * (2 * $fRadius)
                $sInfo = "Grey 4"
            Case 3.5 * (2 * $fRadius) + 0.1 To 4 * (2 * $fRadius)
                $sInfo = "Grey 3"
            Case 4 * (2 * $fRadius) + 0.1 To 4.5 * (2 * $fRadius)
                $sInfo = "White 2"
            Case 4.5 * (2 * $fRadius) + 0.1 To 5 * (2 * $fRadius)
                $sInfo = "White 1"
            Case Else
                $sInfo = "Not on board" 
        EndSwitch

 

Share this post


Link to post
Share on other sites

I modified the code again. Currently it makes no sense to generate the archery board permanently within the main loop. I create a function to create the archery board bitmap which will be copied only to the GUI within main loop which improves the speed.

Of course you can change the code to click somewhere in the GUI to get your points. ;)


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

Thanks UEZ, I appreciate your efforts here! :D

Some more info, if you're interested in why i'm doing this. :yawn:

I'm building this tool for our Scout troop so they can easily log scores over multiple sessions. Providing averages and other statistics to help them improve over time. 
Would be cool if I can go as far as showing on the board where they shot in previous sessions and maybe even every shot they have ever done. (Must remind myself to do the basics first ha)

Next task is to build a db to store the scouts name and shot data and calculate averages and all that.   All good fun, the things we Scout leaders think we can achieve! lol

 

Share this post


Link to post
Share on other sites

That's easy, you can store all values, everytime you click, store X and Y.


Spoiler

Renamer - Rename files and folders, remove portions of text from the filename etc.

GPO Tool - Export/Import Group policy settings.

MirrorDir - Synchronize/Backup/Mirror Folders

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

String Trigger - Triggers pasting text or applications or internet links on specific strings.

Inconspicuous - Hide files in plain sight, not fully encrypted.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

IUIAutomation - Topic with framework and examples

Au3Record.exe

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  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...