TubbyWs Posted November 20, 2023 Share Posted November 20, 2023 expandcollapse popup#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 More sharing options...
TubbyWs Posted November 20, 2023 Author Share Posted November 20, 2023 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 More sharing options...
UEZ Posted November 20, 2023 Share Posted November 20, 2023 Do you have the arrow.png file? 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 More sharing options...
Solution UEZ Posted November 20, 2023 Solution Share Posted November 20, 2023 (edited) Here a generic one: expandcollapse popup#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 November 20, 2023 by UEZ TubbyWs 1 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 More sharing options...
TubbyWs Posted November 20, 2023 Author Share Posted November 20, 2023 23 minutes ago, UEZ said: Here a generic one: expandcollapse popup#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 More sharing options...
TubbyWs Posted November 21, 2023 Author Share Posted November 21, 2023 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 : expandcollapse popup#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 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 More sharing options...
UEZ Posted November 21, 2023 Share Posted November 21, 2023 (edited) 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: expandcollapse popup#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 November 21, 2023 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now