Jump to content

Detecting when GDI is facing button control


TubbyWs
 Share

Go to solution Solved by UEZ,

Recommended Posts

#include <WinAPIHObj.au3>
#include <GDIPlus.au3>
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>


Local $secondhandle = WinGetHandle("Toontown Rewritten")

Global $hGUI, $btnPointOne, $Pic1, $PicPos, $hImage, $hGraph, $drawn, $hMatrix

$hGUI = GUICreate("2D Visual", 801, 601, 192, 125)
$btnPointOne = GUICtrlCreateButton("Point One", 128, 144, 100, 30)
$Pic1 = GUICtrlCreatePic("", 352, 504, 89, 73)
GUISetState(@SW_SHOW)

; Wait for the GUI to be shown before getting the position
WinWait($hGUI)

$PicPos = ControlGetPos($hGUI, "", $Pic1)
_GDIPlus_Startup()

$hImage = _GDIPlus_ImageLoadFromFile("Arrow.png")

$hGraph = _GDIPlus_GraphicsCreateFromHWND($hGUI) ; Use the entire GUI handle
$hMatrix = _GDIPlus_MatrixCreate()

While 1

       If _IsPressed("20") Then
                ConsoleWrite("_IsPressed - Key Pressed" & @CRLF)
                ; Wait until key is released.
                While _IsPressed("20")


                       ; Translate to the rotation point
    _GDIPlus_MatrixTranslate($hMatrix, $PicPos[0] + $PicPos[2] / 2, $PicPos[1] + $PicPos[3] / 2)

    ; Rotate the image
    _GDIPlus_MatrixRotate($hMatrix, 1.45)

    ; Translate back to the original position
    _GDIPlus_MatrixTranslate($hMatrix, -($PicPos[0] + $PicPos[2] / 2), -($PicPos[1] + $PicPos[3] / 2))

    ; Draw the rotated image
    _GDIPlus_GraphicsDrawImageRect($hGraph, $hImage, $PicPos[0], $PicPos[1], $PicPos[2], $PicPos[3])

    ; Apply the rotation matrix
    _GDIPlus_GraphicsSetTransform($hGraph, $hMatrix)

    ; Update the GUI
    GUISetState(@SW_SHOW)

    ; Sleep for a short duration to control rotation speed
    Sleep(1)

                WEnd
                ConsoleWrite("_IsPressed - Key Released." & @CRLF)

        EndIf

WEnd

; Dispose of the resources
_GDIPlus_MatrixDispose($hMatrix)
_GDIPlus_ImageDispose($hImage)
_GDIPlus_GraphicsDispose($hGraph)
_GDIPlus_Shutdown()

 

Hi everyone, I'm trying to figure out how I can detect when the _GDI Image is pointing at the button? To be honest, I am pretty dumb in math and I don't really know how to do this. I have tried ChatGPT but it never gives a working solution, and I have scowered for the answer for hours to no avail before I have finally decided I need help from you guys. How can I detect when the GDI Image is facing the button? Being able to do this would be very neat for quite a few things I am working on. Much love, thanks. 

Link to comment
Share on other sites

By the way, regarding the handle at the top of the script, please don't be concerned. It's a leftover element from a previous project unrelated to this code. The earlier project involved arranging instances of the window neatly on my screen in a GUI, I wasn't automating the game or anything and multiboxing is allowed. Instead of developing a new GUI from scratch, I utilized the existing one as a foundation for the current project. Much love, thanks.

Link to comment
Share on other sites

  • Solution

Here a generic one:

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

_GDIPlus_Startup()
$hGUI = GUICreate("", 800, 600)
GUISetState()

$hGfx = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromScan0(800, 600)
$hCanvas = _GDIPlus_ImageGetGraphicsContext($hBitmap)
$hBrush = _GDIPlus_BrushCreateSolid(0xFF00FF00)
$hPen = _GDIPlus_PenCreate(0xFF000000)
$x = Random(100, 700)
$y = Random(50, 150)
$w = Random(50, 100)
$h = Random(50, 100)

$xp = 400
$yp = 500
$r = 800

$a = 0

Do
    _GDIPlus_GraphicsClear($hCanvas, 0xFFFFFFFF)
    _GDIPlus_GraphicsFillRect($hCanvas, $x, $y, $w, $h, $hBrush)
    $px = $xp + Cos($a) * $r
    $py = $yp + Sin($a) * $r
    _GDIPlus_GraphicsDrawLine($hCanvas, $xp, $yp, $px, $py, $hPen)
    If LineRectCollision($xp, $yp, $px, $py, $x, $y, $x + $w, $y + $h) Then
        _GDIPlus_BrushSetSolidColor($hBrush, 0xFFFF0000)
    Else
        _GDIPlus_BrushSetSolidColor($hBrush, 0xFF00FF00)
    EndIf
    $a -= 0.03
    _GDIPlus_GraphicsDrawImageRect($hGfx, $hBitmap, 0, 0, 800, 600)
Until GUIGetMsg() = $GUI_EVENT_CLOSE

_GDIPlus_PenDispose($hPen)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($hCanvas)
_GDIPlus_GraphicsDispose($hGfx)
_GDIPlus_ImageDispose($hBitmap)


Func LineRectCollision($x1, $y1, $x2, $y2, $rectLeft, $rectTop, $rectRight, $rectBottom)
    ; Check if the starting point is inside the rectangle
    If $x1 >= $rectLeft And $x1 <= $rectRight And $y1 >= $rectTop And $y1 <= $rectBottom Then
        Return True
    EndIf

    Local $m = ($y2 - $y1) / ($x2 - $x1) ; Slope of the line
    Local $b = $y1 - $m * $x1 ; y-intercept of the line

    ; Check for intersection with each side of the rectangle
    If (($m * $rectLeft + $b >= $rectTop And $m * $rectLeft + $b <= $rectBottom) Or _
        ($m * $rectRight + $b >= $rectTop And $m * $rectRight + $b <= $rectBottom) Or _
        (($rectTop - $b) / $m >= $rectLeft And ($rectTop - $b) / $m <= $rectRight) Or _
        (($rectBottom - $b) / $m >= $rectLeft And ($rectBottom - $b) / $m <= $rectRight)) Then
        ; Check if the line is moving towards the rectangle
        If ($x2 - $x1) * ($rectRight - $rectLeft) + ($y2 - $y1) * ($rectBottom - $rectTop) < 0 Then
            Return True ; Line intersects with the rectangle
        EndIf
    EndIf

    Return False ; No intersection
EndFunc

 

 

Edited by UEZ

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

23 minutes ago, UEZ said:

Here a generic one:

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

_GDIPlus_Startup()
$hGUI = GUICreate("", 800, 600)
GUISetState()

$hGfx = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromScan0(800, 600)
$hCanvas = _GDIPlus_ImageGetGraphicsContext($hBitmap)
$hBrush = _GDIPlus_BrushCreateSolid(0xFF00FF00)
$hPen = _GDIPlus_PenCreate(0xFF000000)
$x = Random(100, 700)
$y = Random(50, 150)
$w = Random(50, 100)
$h = Random(50, 100)

$xp = 400
$yp = 500
$r = 800

$a = 0

Do
    _GDIPlus_GraphicsClear($hCanvas, 0xFFFFFFFF)
    _GDIPlus_GraphicsFillRect($hCanvas, $x, $y, $w, $h, $hBrush)
    $px = $xp + Cos($a) * $r
    $py = $yp + Sin($a) * $r
    _GDIPlus_GraphicsDrawLine($hCanvas, $xp, $yp, $px, $py, $hPen)
    If LineRectCollision($xp, $yp, $px, $py, $x, $y, $x + $w, $y + $h) Then
        _GDIPlus_BrushSetSolidColor($hBrush, 0xFFFF0000)
    Else
        _GDIPlus_BrushSetSolidColor($hBrush, 0xFF00FF00)
    EndIf
    $a -= 0.03
    _GDIPlus_GraphicsDrawImageRect($hGfx, $hBitmap, 0, 0, 800, 600)
Until GUIGetMsg() = $GUI_EVENT_CLOSE

_GDIPlus_PenDispose($hPen)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($hCanvas)
_GDIPlus_GraphicsDispose($hGfx)
_GDIPlus_ImageDispose($hBitmap)


Func LineRectCollision($x1, $y1, $x2, $y2, $rectLeft, $rectTop, $rectRight, $rectBottom)
    ; Check if the starting point is inside the rectangle
    If $x1 >= $rectLeft And $x1 <= $rectRight And $y1 >= $rectTop And $y1 <= $rectBottom Then
        Return True
    EndIf

    Local $m = ($y2 - $y1) / ($x2 - $x1) ; Slope of the line
    Local $b = $y1 - $m * $x1 ; y-intercept of the line

    ; Check for intersection with each side of the rectangle
    If (($m * $rectLeft + $b >= $rectTop And $m * $rectLeft + $b <= $rectBottom) Or _
        ($m * $rectRight + $b >= $rectTop And $m * $rectRight + $b <= $rectBottom) Or _
        (($rectTop - $b) / $m >= $rectLeft And ($rectTop - $b) / $m <= $rectRight) Or _
        (($rectBottom - $b) / $m >= $rectLeft And ($rectBottom - $b) / $m <= $rectRight)) Then
        ; Check if the line is moving towards the rectangle
        If ($x2 - $x1) * ($rectRight - $rectLeft) + ($y2 - $y1) * ($rectBottom - $rectTop) < 0 Then
            Return True ; Line intersects with the rectangle
        EndIf
    EndIf

    Return False ; No intersection
EndFunc

 

 

Thank you!! 

Link to comment
Share on other sites

Hi thanks a lot for your help, your example is just what I was looking for. I do have another issue though. I am trying to make it so that I can set the arrow to $Button2 and the box to $Button1 (To more easily change the green box and the arrows position, as I am much more familiar with moving GUI's than GDI's. ). I have had some success, for example, this works : 

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WinAPIHObj.au3>
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>


_GDIPlus_Startup()
$hGUI = GUICreate("", 800, 600)
$Button1 = GUICtrlCreateButton("1", 544, 200, 25, 25)
$Button2 = GUICtrlCreateButton("2", 360, 344, 25, 25)
$ButtonPos = ControlGetPos($hGUI,"",$Button1)
$ButtonPos2 = ControlGetPos($hGUI,"",$Button2)
GUISetState()

$hGfx = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromScan0(800, 600)
$hCanvas = _GDIPlus_ImageGetGraphicsContext($hBitmap)
$hBrush = _GDIPlus_BrushCreateSolid(0xFF00FF00)
$hPen = _GDIPlus_PenCreate(0xFF000000)
$x = $ButtonPos[0]
$y = $ButtonPos[1]
$w = $ButtonPos[2]
$h = $ButtonPos[3]

$xp = $ButtonPos2[0]
$yp = $ButtonPos2[1]
$r = 800

$a = 0

Do


       If _IsPressed("20") Then
                ConsoleWrite("_IsPressed - Key was pressed." & @CRLF)
                ; Wait until key is released.
                While _IsPressed("20")
                    $ButtonPos = ControlGetPos($hGUI,"",$Button1)
                    $ButtonPos2 = ControlGetPos($hGUI,"",$Button2)
GuiCtrlSetPos($Button1,$ButtonPos[0] + 0.5,$ButtonPos[1] - 1,$w,$h)
GuiCtrlSetPos($Button2,$ButtonPos2[0] - 0.5,$ButtonPos2[1] + 1,$w,$h)
$x = $ButtonPos[0]
$y = $ButtonPos[1]
$w = $ButtonPos[2]
$h = $ButtonPos[3]

$xp = $ButtonPos2[0]
$yp = $ButtonPos2[1]
$r = 800


   _GDIPlus_GraphicsClear($hCanvas, 0xFFFFFFFF)
    _GDIPlus_GraphicsFillRect($hCanvas, $x, $y, $w, $h, $hBrush)
    $px = $xp + Cos($a) * $r
    $py = $yp + Sin($a) * $r
    _GDIPlus_GraphicsDrawLine($hCanvas, $xp, $yp, $px, $py, $hPen)
    If LineRectCollision($xp, $yp, $px, $py, $x, $y, $x + $w, $y + $h) Then
        _GDIPlus_BrushSetSolidColor($hBrush, 0xFFFF0000)
        msgbox(1,"Collision","Gottem")
    Else
        _GDIPlus_BrushSetSolidColor($hBrush, 0xFF00FF00)
    EndIf
  $a -= 0.01
    _GDIPlus_GraphicsDrawImageRect($hGfx, $hBitmap, 0, 0, 800, 600)


                WEnd
                ConsoleWrite("_IsPressed - Shift Key was released." & @CRLF)

        EndIf


Until GUIGetMsg() = $GUI_EVENT_CLOSE

_GDIPlus_PenDispose($hPen)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($hCanvas)
_GDIPlus_GraphicsDispose($hGfx)
_GDIPlus_ImageDispose($hBitmap)


Func LineRectCollision($x1, $y1, $x2, $y2, $rectLeft, $rectTop, $rectRight, $rectBottom)
    ; Check if the starting point is inside the rectangle
    If $x1 >= $rectLeft And $x1 <= $rectRight And $y1 >= $rectTop And $y1 <= $rectBottom Then
        Return True
    EndIf

    Local $m = ($y2 - $y1) / ($x2 - $x1) ; Slope of the line
    Local $b = $y1 - $m * $x1 ; y-intercept of the line

    ; Check for intersection with each side of the rectangle
    If (($m * $rectLeft + $b >= $rectTop And $m * $rectLeft + $b <= $rectBottom) Or _
        ($m * $rectRight + $b >= $rectTop And $m * $rectRight + $b <= $rectBottom) Or _
        (($rectTop - $b) / $m >= $rectLeft And ($rectTop - $b) / $m <= $rectRight) Or _
        (($rectBottom - $b) / $m >= $rectLeft And ($rectBottom - $b) / $m <= $rectRight)) Then
        ; Check if the line is moving towards the rectangle
        If ($x2 - $x1) * ($rectRight - $rectLeft) + ($y2 - $y1) * ($rectBottom - $rectTop) < 0 Then
            Return True ; Line intersects with the rectangle
        EndIf
    EndIf

    Return False ; No intersection
EndFunc

image.png.13cdc1fe9f69db3dc294493b3471b860.png

 

But oddly enough, if I have $Button2 (where the arrow is at) moving upwards like this : GuiCtrlSetPos($Button2,$ButtonPos2[0] - 0.5,$ButtonPos2[1] - 1,$w,$h)

Or if I have $Button1 (collision box) moving downwards like this : GuiCtrlSetPos($Button1,$ButtonPos[0] + 0.5,$ButtonPos[1] + 1,$w,$h), no collision is detected when the arrow hits the box. 

Link to comment
Share on other sites

Try to use

If ($x2 - $x1) * ($rectRight - $rectLeft) + ($y2 - $y1) * ($rectBottom - $rectTop) > 0 Then

Probably there is a bug in the LineRectCollision function. I need to check it...

 

Edit:

Try this instead:

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WinAPIHObj.au3>
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>


_GDIPlus_Startup()
$hGUI = GUICreate("", 800, 600)
$Button1 = GUICtrlCreateButton("1", 544, 200, 25, 25)
$Button2 = GUICtrlCreateButton("2", 360, 344, 25, 25)
$ButtonPos = ControlGetPos($hGUI, "", $Button1)
$ButtonPos2 = ControlGetPos($hGUI, "", $Button2)
GUISetState()

$hGfx = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromScan0(800, 600)
$hCanvas = _GDIPlus_ImageGetGraphicsContext($hBitmap)
$hBrush = _GDIPlus_BrushCreateSolid(0xFF00FF00)
$hPen = _GDIPlus_PenCreate(0xFF000000)
$x = $ButtonPos[0]
$y = $ButtonPos[1]
$w = $ButtonPos[2]
$h = $ButtonPos[3]

$xp = $ButtonPos2[0]
$yp = $ButtonPos2[1]
$r = 800

$a = 0

Do


    If _IsPressed("20") Then
        ConsoleWrite("_IsPressed - Key was pressed." & @CRLF)
        ; Wait until key is released.
        While _IsPressed("20")
            $x -= 0.5
            $y += 1
            GUICtrlSetPos($Button1, $x, $y, $w, $h)
            $xp += 0.5
            $yp += 1
            GUICtrlSetPos($Button2, $xp, $yp, $w, $h)

            _GDIPlus_GraphicsClear($hCanvas, 0xFFFFFFFF)
            _GDIPlus_GraphicsFillRect($hCanvas, $x, $y, $w, $h, $hBrush)
            $px = $xp + Cos($a) * $r
            $py = $yp + Sin($a) * $r
            _GDIPlus_GraphicsDrawLine($hCanvas, $xp, $yp, $px, $py, $hPen)
            If LineRectCollision($xp, $yp, $px, $py, $x, $y, $x + $w, $y + $h) Then
                _GDIPlus_BrushSetSolidColor($hBrush, 0xFFFF0000)
                MsgBox(1, "Collision", "Gottem")
            Else
                _GDIPlus_BrushSetSolidColor($hBrush, 0xFF00FF00)
            EndIf
            $a -= 0.01
            _GDIPlus_GraphicsDrawImageRect($hGfx, $hBitmap, 0, 0, 800, 600)

        WEnd
        ConsoleWrite("_IsPressed - Shift Key was released." & @CRLF)

    EndIf


Until GUIGetMsg() = $GUI_EVENT_CLOSE

_GDIPlus_PenDispose($hPen)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($hCanvas)
_GDIPlus_GraphicsDispose($hGfx)
_GDIPlus_ImageDispose($hBitmap)


Func LineRectCollision($x1, $y1, $x2, $y2, $rectLeft, $rectTop, $rectRight, $rectBottom)
    Local $left =   LineLineCollision($x1, $y1, $x2, $y2, $rectLeft, $rectTop, $rectLeft, $rectBottom)
    Local $right =  LineLineCollision($x1, $y1, $x2, $y2, $rectRight, $rectTop, $rectRight, $rectBottom)
    Local $top =    LineLineCollision($x1, $y1, $x2, $y2, $rectLeft, $rectTop, $rectRight, $rectTop)
    Local $bottom = LineLineCollision($x1, $y1, $x2, $y2, $rectLeft, $rectBottom, $rectRight, $rectBottom)
    If BitOR($left, $right, $top, $bottom) Then Return True
    Return False
EndFunc

Func LineLineCollision($x1, $y1, $x2, $y2, $x3, $y3, $x4, $y4)
    Local $uA = (($x4 - $x3) * ($y1 - $y3) - ($y4 - $y3) * ($x1 - $x3)) / (($y4 - $y3) * ($x2 - $x1) - ($x4 - $x3) * ($y2 - $y1))
    Local $uB = (($x2 - $x1) * ($y1 - $y3) - ($y2 - $y1) * ($x1 - $x3)) / (($y4 - $y3) * ($x2 - $x1) - ($x4 - $x3) * ($y2 - $y1))
    If BitAND($uA >= 0, $uA <= 1, $uB >= 0, $uB <= 1) Then Return True
    Return False
EndFunc

 

Edited by UEZ

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

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...