Find color closest to cursor and click Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
mamo691
Posts: 41
Joined: 07 Jan 2024, 12:40

Find color closest to cursor and click

31 Mar 2024, 09:17

Code: Select all

c::

CoordMode, Pixel, Screen

PixelSearch, Px, Py, 281, 715, 937, 436, 0x1623FD, 3, Fast
if ErrorLevel
    MsgBox, That color was not found in the specified region.
else

MouseClick, Left, Px, Py

return
[Mod edit: Added [code][/code] tags. Please use them yourself when posting code!]

This is what I have right now. It kinda works but my problem is I need it to CTRL+click on the color that is closest to my cursor. Not just click on color that is between coordinates. I have put a image to show you what im using it for. So basically this is what I want. I would GREATLY appreciate if you could make it possible so that it will do 3 CTRL+clicks on 3 different spots where color is found and is nearest to my cursor. I WOULD GREATLY APPRECIATE THIS, THANK YOU.
Attachments
1c98d75887132cd08383e9adf571430e.png
1c98d75887132cd08383e9adf571430e.png (173.92 KiB) Viewed 533 times
gregster
Posts: 9036
Joined: 30 Sep 2013, 06:48

Re: Find color closest to cursor and click

31 Mar 2024, 09:46

@mamo691, please use code tags when posting code, so that the moderators don't have to edit your posts. Thank you!

ctags.png
ctags.png (14.18 KiB) Viewed 528 times
mamo691
Posts: 41
Joined: 07 Jan 2024, 12:40

Re: Find color closest to cursor and click

31 Mar 2024, 09:47

alright can you help me with the question
User avatar
Chunjee
Posts: 1423
Joined: 18 Apr 2014, 19:05
Contact:

Re: Find color closest to cursor and click

31 Mar 2024, 10:06

Since pixelsearch only returns one match, you will need pixelSearchAll() or similar. Might I suggest https://github.com/Chunjee/graphicsearch.ahk ?

Then calculate the distance from the cursor forEach. graphicsearch.ahk has .resultSortDistance which uses Pythagorean theorem to measure the distance to a given point.

After calculation, sort by the lowest number (the closest)

Finally, send the click to the location
mamo691
Posts: 41
Joined: 07 Jan 2024, 12:40

Re: Find color closest to cursor and click

31 Mar 2024, 10:24

@Chunjee @mikeyww

viewtopic.php?t=96897

Cant you make something like this ? Also can you make me a script where when I'm holding down on the "g" key, when my cursor is on color 0x1623FD, I want to send space+click on where my cursor is aka the color.
User avatar
Chunjee
Posts: 1423
Joined: 18 Apr 2014, 19:05
Contact:

Re: Find color closest to cursor and click

31 Mar 2024, 10:33

since some are bigger than others, a function that combines results that are {{x}} close to each other may be useful.

my test query "|<redpixel>[email protected]$6.zzzzzU" found about 110 matches but my human eyes only count 25 so some reduction is needed since the big ones are registering more than once.
User avatar
Chunjee
Posts: 1423
Joined: 18 Apr 2014, 19:05
Contact:

Re: Find color closest to cursor and click

31 Mar 2024, 10:49

this should be pretty simple I heard :think:


Just for my fun, not rigorously tested or production ready

Code: Select all

oGraphicSearch := new graphicsearch() ; requires https://github.com/Chunjee/graphicsearch.ahk

redPixels := "|<redpixel>[email protected]$6.zzzzzU"
resultsObj := oGraphicSearch.search(redPixels)

if (resultsObj) {
	originalFinds := resultsObj.count()
	resultsObj := CombineAndAverageResults(resultsObj, 20)
	msgbox, % originalFinds " found, reduced to " resultsObj.count()
	; sort by closest to {{x}}
	resultsObj := oGraphicSearch.resultSortDistance(resultsObj, 100, 900)
	; => 110 found, reduced to 25
	for i,v in resultsObj {
		graphicsearch.mouseTip(resultsObj[i].x, resultsObj[i].y)
	}
}


; functions
CombineAndAverageResults(resultsObj, tolerance:=5) {
	; Create a new object to store combined and averaged results
	combinedResults := []

	; Loop through each result object
	for index, result in resultsObj {
		; Check if there are any combined results yet
		if (combinedResults.count() = 0) {
			; If no combined results yet, add the current result to combinedResults
			combinedResults.push(result)
		} else {
			; If there are combined results, loop through them to find a match
			matched := false
			for _, combinedResult in combinedResults {
				; Check if the current result is close to the combined result in terms of x and y coordinates
				if (abs(result.x - combinedResult.x) <= tolerance && abs(result.y - combinedResult.y) <= tolerance) {
					; Combine the current result with the matched combined result
					for key, value in result {
						; Skip "id", "x", and "y" properties
						if (key = "id" || key = "x" || key = "y")
							continue
						; Average numerical values
						combinedResult[key] := (combinedResult[key] + value) / 2
					}
					; Set matched flag to true
					matched := true
					; Exit the loop since we found a match
					break
				}
			}
			; If no match found, add the current result as a new combined result
			if (!matched) {
				combinedResults.push(result)
			}
		}
	}

	; Return the combined and averaged results
	return combinedResults
}
mamo691
Posts: 41
Joined: 07 Jan 2024, 12:40

Re: Find color closest to cursor and click

31 Mar 2024, 10:51

Im asking help on a different matter rn.

#SingleInstance, Force
SendMode, Input
SetBatchLines, -1
SetWorkingDir, %A_ScriptDir%

Code: Select all

{
    $g::
        CoordMode, Pixel, Screen
        CoordMode, Mouse, Screen
        MouseGetPos, MouseX, MouseY

        {
            PixelSearch, %MouseX%, %MouseY%, 0, 0, A_ScreenWidth, A_ScreenHeight, 0x1623FD, 1, Fast
            if (ErrorLevel = 0)
            {
                Send, {Space Down}{Click}{Space up}
                Sleep, 1
            }
            else
            {
                Sleep, 1
            }
        }
    return

    2::Reload
    3::ExitApp
}
I dont want it to do space+clicks when the cursor is not on the color... Please help me.
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Find color closest to cursor and click

31 Mar 2024, 22:48

This script searches outwards from your cursor position to a max range and then starts over again.

.
pixel search range.gif
pixel search range.gif (212.63 KiB) Viewed 416 times
.

The rate that it expands the search radius and the max radius are variable. ( i.e. you can change them )

Code: Select all

#SingleInstance, Force
#NoEnv
SetBatchLines, -1
CoordMode, Mouse, Screen
CoordMode, Pixel, Screen
CoordMode, ToolTip, Screen
;********************
color 		:= "0x000000"
variation 	:= 0
range 		:= 50
rate 		:= 1 
stop 		:= 1
;********************
return
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&;
*ESC::ExitApp
;********************
F4:: ;{ stop script
	Stop := 1
	return
;}	
;********************
F3:: ;{ set color variation
	stop := 1
	sleep, 60
	InputBox, variation, Color Variation, Set the color variation`nRange: 0-255 
	if( variation = "" )
		variation := 0
	return
;}
;********************	
F2:: ;{ set color
	stop := 1
	sleep, 60
	Gui, New, +AlwaysOnTop +hwndColorGui -DPIScale -Caption +Border
	While( !GetKeyState( "Ctrl" ) ){
		MouseGetPos, sx , sy
		ToolTip, Hover your cursor over a color and then press the "ctrl" key , % sx + 30 , % sy + 20
		PixelGetColor, color, sx, sy, RGB Fast
		Gui, % ColorGui ":Color", % color
		Gui, % ColorGui ":Show", % "x" sx + 100 " y" sy - 30 " w" 40 " h" 40 " NA"
	}
	ToolTip
	While( GetKeyState( "Ctrl" ) )
		Sleep, 10
	While( !GetKeyState( "Ctrl" ) ){
		ToolTip, Move your cursor away from the color and press "ctrl" again.`nThis is mainly for cases where`nyour mouse changes the color`nthat you want when it is over it.
		PixelGetColor, color, sx, sy, RGB Fast
		Gui, % ColorGui ":Color", % color
		Gui, % ColorGui ":Show", % "x" sx + 100 " y" sy - 20 " w" 40 " h" 40 " NA"
	}
	ToolTip
	While( GetKeyState( "Ctrl" ) )
		Sleep, 10
	Gui, % ColorGui ":Destroy"
	SoundBeep
	SoundBeep, 600
	return
;}	
;********************	
F1:: ;{ start search
	SoundBeep
	SoundBeep, 600
	stop := 0
	dist := 1
	MouseGetPos, cx, cy 
	lx := cx 
	ly := cy
	While( !stop ){
		MouseGetPos, cx, cy 
		if( cx != lx || cy != ly ){
			lx := cx 
			ly := cy
			dist := 1
		}
		sx := cx - dist
		ex := cx + dist
		sy := cy - dist
		ey := cy + dist
		PixelSearch, tx, ty, sx, sy, ex, ey, % color, % variation, RGB Fast
		if( !ErrorLevel ){
			MouseMove, tx, ty
			dist := 1
			if( stop )
				break
		}
		if( ( dist += rate ) > range )
			dist := 1
	}
	SoundBeep,999
	SoundBeep,777
	SoundBeep,555
	return
;}	
;********************
This is a better visualization of how it works.
Note that it prioritizes matches of top over bottom and left over right, this is why in the gif it follows the black line to the left over time.

.
pixel search range 2.gif
pixel search range 2.gif (247.12 KiB) Viewed 416 times
.
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Find color closest to cursor and click

02 Apr 2024, 11:35

Chunjee wrote:
01 Apr 2024, 08:30
I wanted to make a gif too
That looks really cool :thumbup:
I assume that you are using some sort of a grid search and then checking the distance to get the order to do your actions?


It inspired me to edit my version to handle multiple targets.

.
pixel search range 5.gif
pixel search range 5.gif (1.04 MiB) Viewed 375 times
.

Code: Select all

#SingleInstance, Force
#NoEnv
SetBatchLines, -1
CoordMode, Mouse, Screen
CoordMode, Pixel, Screen
CoordMode, ToolTip, Screen
SetWinDelay, -1
SetMouseDelay, -1
SetDefaultMouseSpeed, 0
;********************
;~ color 		:= "0x000000"
color 		:= "0xFE0C03"
variation 	:= 99
;~ range 		:= 450
range 		:= 544
;~ rate 		:= 30
rate 		:= 50
stop 		:= 1
maxblocks 	:= 50
Delay 	:= 1000
;********************
return
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&;
*ESC::ExitApp
;********************
F4:: ;{ stop script
	Stop := 1
	return
;}	
;********************
F3:: ;{ set color variation
	stop := 1
	sleep, 60
	InputBox, variation, Color Variation, Set the color variation`nRange: 0-255 
	if( variation = "" )
		variation := 0
	return
;}
;********************	
F2:: ;{ set color
	stop := 1
	sleep, 60
	Gui, New, +AlwaysOnTop +hwndColorGui -DPIScale -Caption +Border
	While( !GetKeyState( "Ctrl" ) ){
		MouseGetPos, sx , sy
		ToolTip, Hover your cursor over a color and then press the "ctrl" key , % sx + 30 , % sy + 20
		PixelGetColor, color, sx, sy, RGB Fast
		Gui, % ColorGui ":Color", % color
		Gui, % ColorGui ":Show", % "x" sx + 100 " y" sy - 30 " w" 40 " h" 40 " NA"
	}
	ToolTip
	While( GetKeyState( "Ctrl" ) )
		Sleep, 10
	While( !GetKeyState( "Ctrl" ) ){
		ToolTip, Move your cursor away from the color and press "ctrl" again.`nThis is mainly for cases where`nyour mouse changes the color`nthat you want when it is over it.
		PixelGetColor, color, sx, sy, RGB Fast
		Gui, % ColorGui ":Color", % color
		Gui, % ColorGui ":Show", % "x" sx + 100 " y" sy - 20 " w" 40 " h" 40 " NA"
	}
	ToolTip
	While( GetKeyState( "Ctrl" ) )
		Sleep, 10
	Gui, % ColorGui ":Destroy"
	SoundBeep
	SoundBeep, 600
	return
;}	
;********************	
F1:: ;{ start search
	SoundBeep
	SoundBeep, 600
	stop := 0
	dist := 1
	MouseGetPos, cx, cy 
	lx := cx 
	ly := cy
	Gui, t:+AlwaysOnTop -Caption +Border +LastFound
	WinSet, TransColor, f0f0f0
	windows := []
	count := 0
	While( !stop ){
		
		MouseGetPos, cx, cy 
		if( cx != lx || cy != ly ){
			lx := cx 
			ly := cy
			dist := 1
		}
		sx := cx - dist
		ex := cx + dist
		sy := cy - dist
		ey := cy + dist
		Gui, t:Show, % "x" sx  " y" sy " w" ex - sx " h" ey - sy " NA"
		PixelSearch, tx, ty, sx, sy, ex, ey, % color, % variation, RGB Fast
		if( !ErrorLevel ){
			MouseMove, tx, ty
			dist := 1
			Gui, New, +AlwaysOnTop -Caption -DPIScale +ToolWindow +hwndhwnd
			windows.Push( hwnd )
			Gui, Color, 22262a
			Gui, Show, % "x" tx - rate / 2 " y" ty - rate / 2 " w" rate " h" rate " NA"
			if( tx < range / 2 && ty < range / 2 )
				MouseMove, tx + range / 2 , ty + range / 2
			else if( tx < range / 2 )
				MouseMove, tx + range / 2 , ty
			else if( ty < range / 2 )
				MouseMove, tx, ty + range / 2
			else if( tx > A_ScreenWidth - range / 2 && ty > A_ScreenHeight - range / 2 )
				MouseMove, tx - range / 2 - 2, ty - range / 2 - 1
			else if( tx > A_ScreenWidth - range / 2 )
				MouseMove, tx - range / 2 - 2 , ty 
			else if( ty > A_ScreenHeight - range / 2 )
				MouseMove, tx , ty - range / 2 - 2
			if( stop )
				break
			if( ++count > maxblocks && count := maxblocks ){
				Gui, % windows[ 1 ] ":Destroy"
				windows.Remove( 1 )
			}
		}
		if( ( dist += rate ) > range )
			dist := 1
		if( !startTime ){
				startTime := A_TickCount
			}
		if( StartTime && ( A_TickCount - Delay ) > StartTime ){
				startTime := 0 
				if( windows.Length() ){
					count--
					Gui, % windows[ 1 ] ":Destroy"
					windows.Remove( 1 )
				}
		}
	}
	for k , v in windows	{
		Gui, % windows[ k ] ":Destroy"
	}
	Gui, t:Destroy
	SoundBeep,999
	SoundBeep,777
	SoundBeep,555
	return
;}	
;********************
User avatar
Chunjee
Posts: 1423
Joined: 18 Apr 2014, 19:05
Contact:

Re: Find color closest to cursor and click

02 Apr 2024, 12:01

Yeah it was the code I posted earlier in the day.

The sorting comes from .resultsSortDistance

Prior to that I belive the search is plain left to right
mamo691
Posts: 41
Joined: 07 Jan 2024, 12:40

Re: Find color closest to cursor and click

03 Apr 2024, 12:54

@Hellbent Bro thank you so much for your effort, the script you gave works perfectly. But it doesnt really solve my problem. What I want is that I want to send only one space (hold space key)+click onto the detected colour that is closest near my cursor in the range. I also if possible asked to be able to do combinations. Like not just this, but, like find 3 closest detected colours to my cursor in range then send each one of them only one space+click. This process will happen while I'm holding the trigger key which is "g", and when I stop holding this key, it needs to stop holding space, and stop clicking. I would very much be happy if you made this possible. I am using a different code right now which just detects if the color is under my cursor and then sends click which @Chunjee thanks to him gave me but yeah, your code would be perfect for me if you made this changes possible.

(heres the script im using rn btw)

Code: Select all


g::
while (GetKeyState("g")) {
    MouseGetPos, MouseX, MouseY
    PixelSearch, FoundX, FoundY, MouseX, MouseY, MouseX, MouseY, 0x030AFE , 6, Fast
    if (FoundX) {
        
        Send, {Space Down}{Click}
    }

else

Send, {Space Up}
    
}  
return
User avatar
Chunjee
Posts: 1423
Joined: 18 Apr 2014, 19:05
Contact:

Re: Find color closest to cursor and click

03 Apr 2024, 15:09

this is my first time hearing about matching three possible different colors.


I would use an array
ForEach() {
if match { sortClosest => click location }
}

You get the general idea
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Find color closest to cursor and click  Topic is solved

04 Apr 2024, 01:43

mamo691 wrote:
03 Apr 2024, 12:54
What I want is that I want to send only one space (hold space key)+click onto the detected colour that is closest near my cursor in the range.
My code was only set to move the cursor, you would need to edit that action so that it does what you need.

Here I replaced the old "MouseMove" with a function that contains the operations to preform.

Code: Select all

;BEFORE:
MouseMove, tx , ty

;NOW:
Action_Function_1( tx , ty )
The function itself looks like this.

Code: Select all

;********************
;When the color is found it runs this code.
Action_Function_1( x , y ){ ;<--- You can "pass" as many arguments as you need to. In this example I am just passing the x and y values for where the color was found.
	
	;~ MouseMove, x, y 							;example of moving the cursor.
	;~ Sleep, 500			
	;********************
	;This is the action you asked for.
	send, { Space, Down } 					;hold the space key down
	sleep, 30								;wait a fraction of a second
	Send, % "{ Click , " x " , " y " }"		;send a click
	sleep, 30								;wait a fraction of a second
	send, { Space, Up }						;release the space key.
	sleep, 30								;wait a fraction of a second
	;********************
	
	return 1
	
}
;********************
I also if possible asked to be able to do combinations. Like not just this, but, like find 3 closest detected colours to my cursor in range then send each one of them only one space+click. This process will happen while I'm holding the trigger key which is "g", and when I stop holding this key, it needs to stop holding space, and stop clicking. I would very much be happy if you made this possible.

The script has been modified to use "g" as the hotkey, press it and the script will start looking for up to 3 target matches before you have to press the hotkey again.

The amount of target matches is adjustable, so for example you can set it to find 5 or 10 matches, or you can set it to have no limit by setting it to zero.

Here is the variable to find and edit.

Code: Select all

maxFinds	:= 3
The script works by creating a search area that radiates outwards from the cursors current position, the rate that expands is variable.
If the rate of expansion is large, the results for "closest" won't be perfect but will be with in the expansion rate.

i.e. set the rate to a value of "1" and the margin of error is 0 pixels, set the rate to 50 and the margin of error is 49 pixels.

This example shows the use of different values of the "rate" variable.
Note how the search area starts over when the cursor moves, whenever a match is found the script will reset the search area and find the next match based on the current position.

.
pixel search range 7.gif
pixel search range 7.gif (555.06 KiB) Viewed 309 times
.

Here are a few more thins you can adjust.

- You can adjust the number of matches to make before it stops.
- You can use a mask block if the target stays on screen.
- You can change the size of the mask blocks.
- You can set the max number of masking blocks that can be on screen before they start disappearing in sequence.
- If you don't need a mask you can comment out the 3-4 lines of code that handle displaying the block windows.

Example of adjusting the block sizes.

.
pixel search range 8.gif
pixel search range 8.gif (501.94 KiB) Viewed 309 times
.

Code: Select all

#SingleInstance, Force
#NoEnv
SetBatchLines, -1
CoordMode, Mouse, Screen
CoordMode, Pixel, Screen
CoordMode, ToolTip, Screen
SetWinDelay, -1
SetMouseDelay, -1
SetDefaultMouseSpeed, 0
;********************
;~ color 		:= "0x000000"
color 		:= "0xFD0B03"
variation 	:= 20
range 		:= 300
rate 		:= 50
stop 		:= 1
blockSize 	:= 60
maxFinds	:= 3
maxblocks 	:= 50
Delay 		:= 10000
currentFinds:= 0
;********************
return
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&;
*ESC::ExitApp
;********************
F4:: ;{ stop script
	Stop := 1
	return
;}	
;********************
F3:: ;{ set color variation
	stop := 1
	sleep, 60
	InputBox, variation, Color Variation, Set the color variation`nRange: 0-255 
	if( variation = "" )
		variation := 0
	return
;}
;********************	
F2:: ;{ set color
	stop := 1
	sleep, 60
	Gui, New, +AlwaysOnTop +hwndColorGui -DPIScale -Caption +Border
	While( !GetKeyState( "Ctrl" ) ){
		MouseGetPos, sx , sy
		ToolTip, Hover your cursor over a color and then press the "ctrl" key , % sx + 30 , % sy + 20
		PixelGetColor, color, sx, sy, RGB Fast
		Gui, % ColorGui ":Color", % color
		Gui, % ColorGui ":Show", % "x" sx + 100 " y" sy - 30 " w" 40 " h" 40 " NA"
	}
	ToolTip
	While( GetKeyState( "Ctrl" ) )
		Sleep, 10
	While( !GetKeyState( "Ctrl" ) ){
		ToolTip, Move your cursor away from the color and press "ctrl" again.`nThis is mainly for cases where`nyour mouse changes the color`nthat you want when it is over it.
		PixelGetColor, color, sx, sy, RGB Fast
		Gui, % ColorGui ":Color", % color
		Gui, % ColorGui ":Show", % "x" sx + 100 " y" sy - 20 " w" 40 " h" 40 " NA"
	}
	ToolTip
	While( GetKeyState( "Ctrl" ) )
		Sleep, 10
	Gui, % ColorGui ":Destroy"
	SoundBeep
	SoundBeep, 600
	return
;}	
;********************	
$g:: ;{ start search
	;~ SoundBeep
	;~ SoundBeep, 600
	stop := 0
	dist := 1
	MouseGetPos, cx, cy 
	lx := cx 
	ly := cy
	Gui, t:+AlwaysOnTop -Caption +Border +LastFound +ToolWindow
	WinSet, TransColor, f0f0f0
	windows := []
	count := 0
	currentFinds:= 0
	;~ While( !stop ){
	While( GetKeyState( "g" , "p" ) ){
		
		MouseGetPos, cx, cy 
		if( cx != lx || cy != ly ){
			lx := cx 
			ly := cy
			dist := 1
		}
		sx := cx - dist
		ex := cx + dist
		sy := cy - dist
		ey := cy + dist
		Gui, t:Show, % "x" sx  " y" sy " w" ex - sx " h" ey - sy " NA"
		PixelSearch, tx, ty, sx, sy, ex, ey, % color, % variation, RGB Fast
		if( !ErrorLevel ){
			++currentFinds
			
			;********************
			Action_Function_1( tx , ty , move ) ;<<<<<-----  Call the function that contains the actions to perform if the color is found. Passing the found x and found y values.
			;********************
			
			dist := 1
			Gui, New, +AlwaysOnTop -Caption -DPIScale +ToolWindow +hwndhwnd +E0x20
			windows.Push( hwnd )
			Gui, Color, 22262a
			Gui, Show, % "x" tx - blockSize / 2 " y" ty - blockSize / 2 " w" blockSize " h" blockSize " NA"
			Sleep, 30
			if( tx < range / 2 && ty < range / 2 )
				MouseMove, tx + range / 2 , ty + range / 2
			else if( tx < range / 2 )
				MouseMove, tx + range / 2 , ty
			else if( ty < range / 2 )
				MouseMove, tx, ty + range / 2
			else if( tx > A_ScreenWidth - range / 2 && ty > A_ScreenHeight - range / 2 )
				MouseMove, tx - range / 2 - 2, ty - range / 2 - 1
			else if( tx > A_ScreenWidth - range / 2 )
				MouseMove, tx - range / 2 - 2 , ty 
			else if( ty > A_ScreenHeight - range / 2 )
				MouseMove, tx , ty - range / 2 - 2
			if( stop )
				break
			if( ++count > maxblocks && count := maxblocks ){
				Gui, % windows[ 1 ] ":Destroy"
				windows.Remove( 1 )
			}
			if( currentFinds = maxFinds && maxFinds ){
				break
			}
			sleep, 30
		}
		if( ( dist += rate ) > range )
			dist := 1
		if( !startTime ){
				startTime := A_TickCount
			}
		if( StartTime && ( A_TickCount - Delay ) > StartTime ){
				startTime := 0 
				if( windows.Length() ){
					count--
					Gui, % windows[ 1 ] ":Destroy"
					windows.Remove( 1 )
				}
		}
	}
	;~ sleep, 500
	for k , v in windows	{
		Gui, % windows[ k ] ":Destroy"
	}
	Gui, t:Destroy
	KeyWait, g
	return
;}	
;********************
;********************
;********************
;When the color is found it runs this code.
Action_Function_1( x , y , move := 0 ){ ;<--- You can "pass" as many arguments as you need to. In this example I am just passing the x and y values for where the color was found.
	
	;~ MouseMove, x, y 							;example of moving the cursor.
	;~ Sleep, 500			
	;********************
	;This is the action you asked for.
	send, { Space, Down } 					;hold the space key down
	sleep, 30								;wait a fraction of a second
	Send, % "{ Click , " x " , " y " }"		;send a click
	sleep, 30								;wait a fraction of a second
	send, { Space, Up }						;release the space key.
	sleep, 30								;wait a fraction of a second
	;********************
	
	return 1
	
}
;********************
User avatar
Chunjee
Posts: 1423
Joined: 18 Apr 2014, 19:05
Contact:

Re: Find color closest to cursor and click

05 Apr 2024, 10:05

You didn't use any arrays :think:


What if user wanted to find a purple pixel or a green one? Not just variations :lolno:
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Re: Find color closest to cursor and click

05 Apr 2024, 23:05

Chunjee wrote:
05 Apr 2024, 10:05
You didn't use any arrays :think:


What if user wanted to find a purple pixel or a green one? Not just variations :lolno:

I added an array to hold colors but I didn't bother doin it for variation, it can be added easily by following [ color <---> colorList ] as an example.

Before:

Code: Select all

color 		:= "0xFD0B03"
After:

Code: Select all

colorList := [ "0xFF0000" , "0xFFD800" , "0xFF6A00" , "0xFF00DC" ]

Other than that, all I added was a for loop to cycle through the colors and modified the search to use the color array.

Before:

Code: Select all

Gui, t:Show, % "x" sx - 1 " y" sy - 1 " w" ex - sx + 2 " h" ey - sy + 2 " NA"
PixelSearch, tx, ty, sx, sy, ex, ey, % color, % variation, RGB Fast
;...
;..
;.
;
After:

Code: Select all

Gui, t:Show, % "x" sx - 1 " y" sy - 1 " w" ex - sx + 2 " h" ey - sy + 2 " NA"
for k , v in colorList	{
	PixelSearch, tx, ty, sx, sy, ex, ey, % colorList[ k ], % variation, RGB Fast
	;...
	;..
	;.
	;	
}

.
pixel search range 9.gif
pixel search range 9.gif (487.42 KiB) Viewed 264 times
.

- It is important that the "masking" window color needs to be outside the search color range. ( all colors + variation )

- Some of the code is left obsolete with the changes I made and can be removed.

Code: Select all

#SingleInstance, Force
#NoEnv
SetBatchLines, -1
CoordMode, Mouse, Screen
CoordMode, Pixel, Screen
CoordMode, ToolTip, Screen
SetWinDelay, -1
SetMouseDelay, -1
SetDefaultMouseSpeed, 0
;********************
;~ colorList := [ "0xFF0000" , "0xFFD800" , "0xFF6A00" , "0xFF00DC" , "0xFFD800" , "0x4CFF00" , "0x0026FF" , "0x00FFFF" , "0xB200FF" ]
colorList := [ "0xFF0000" , "0xFFD800" , "0xFF6A00" , "0xFF00DC" ]
;********************
;~ color 		:= "0x000000"
color 		:= "0xFD0B03"
variation 	:= 2
range 		:= 300
rate 		:= 50
stop 		:= 1
blockSize 	:= 60
maxFinds	:= 3
maxblocks 	:= 20
Delay 		:= 10000
currentFinds:= 0
;********************
return
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&;
*ESC::ExitApp
;********************
F4:: ;{ stop script
	Stop := 1
	return
;}	
;********************
F3:: ;{ set color variation
	stop := 1
	sleep, 60
	InputBox, variation, Color Variation, Set the color variation`nRange: 0-255 
	if( variation = "" )
		variation := 0
	return
;}
;********************	
F2:: ;{ set color
	stop := 1
	sleep, 60
	Gui, New, +AlwaysOnTop +hwndColorGui -DPIScale -Caption +Border
	While( !GetKeyState( "Ctrl" ) ){
		MouseGetPos, sx , sy
		ToolTip, Hover your cursor over a color and then press the "ctrl" key , % sx + 30 , % sy + 20
		PixelGetColor, color, sx, sy, RGB Fast
		Gui, % ColorGui ":Color", % color
		Gui, % ColorGui ":Show", % "x" sx + 100 " y" sy - 30 " w" 40 " h" 40 " NA"
	}
	ToolTip
	While( GetKeyState( "Ctrl" ) )
		Sleep, 10
	While( !GetKeyState( "Ctrl" ) ){
		ToolTip, Move your cursor away from the color and press "ctrl" again.`nThis is mainly for cases where`nyour mouse changes the color`nthat you want when it is over it.
		PixelGetColor, color, sx, sy, RGB Fast
		Gui, % ColorGui ":Color", % color
		Gui, % ColorGui ":Show", % "x" sx + 100 " y" sy - 20 " w" 40 " h" 40 " NA"
	}
	ToolTip
	While( GetKeyState( "Ctrl" ) )
		Sleep, 10
	Gui, % ColorGui ":Destroy"
	SoundBeep
	SoundBeep, 600
	return
;}	
;********************	
$g:: ;{ start search
	;~ SoundBeep
	;~ SoundBeep, 600
	stop := 0
	dist := 1
	MouseGetPos, cx, cy 
	lx := cx 
	ly := cy
	Gui, t:+AlwaysOnTop -Caption +Border +LastFound +ToolWindow
	WinSet, TransColor, f0f0f0
	windows := []
	count := 0
	currentFinds:= 0
	;~ While( !stop ){
	While( GetKeyState( "g" , "p" ) ){
		
		MouseGetPos, cx, cy 
		if( cx != lx || cy != ly ){
			lx := cx 
			ly := cy
			dist := 1
		}
		sx := cx - dist
		ex := cx + dist
		sy := cy - dist
		ey := cy + dist
		Gui, t:Show, % "x" sx - 1 " y" sy - 1 " w" ex - sx + 2 " h" ey - sy + 2 " NA"
		for k , v in colorList	{
			;~ PixelSearch, tx, ty, sx, sy, ex, ey, % color, % variation, RGB Fast
			PixelSearch, tx, ty, sx, sy, ex, ey, % colorList[ k ], % variation, RGB Fast
			if( !ErrorLevel ){
				++currentFinds
				
				;********************
				Action_Function_1( tx , ty , move ) ;<<<<<-----  Call the function that contains the actions to perform if the color is found. Passing the found x and found y values.
				;********************
				
				dist := 1
				Gui, New, +AlwaysOnTop -Caption -DPIScale +ToolWindow +hwndhwnd +E0x20
				windows.Push( hwnd )
				Gui, Color, 22262a
				Gui, Show, % "x" tx - blockSize / 2 " y" ty - blockSize / 2 " w" blockSize " h" blockSize " NA"
				;~ Sleep, 30
				if( tx < range / 2 && ty < range / 2 )
					MouseMove, tx + range / 2 , ty + range / 2
				else if( tx < range / 2 )
					MouseMove, tx + range / 2 , ty
				else if( ty < range / 2 )
					MouseMove, tx, ty + range / 2
				else if( tx > A_ScreenWidth - range / 2 && ty > A_ScreenHeight - range / 2 )
					MouseMove, tx - range / 2 - 2, ty - range / 2 - 1
				else if( tx > A_ScreenWidth - range / 2 )
					MouseMove, tx - range / 2 - 2 , ty 
				else if( ty > A_ScreenHeight - range / 2 )
					MouseMove, tx , ty - range / 2 - 2
				if( stop )
					break
				if( ++count > maxblocks && count := maxblocks ){
					Gui, % windows[ 1 ] ":Destroy"
					windows.Remove( 1 )
				}
				if( currentFinds = maxFinds && maxFinds ){
					break
				}
				;~ sleep, 30
			}
		}
		if( ( dist += rate ) > range )
			dist := 1
		if( !startTime ){
				startTime := A_TickCount
			}
		if( StartTime && ( A_TickCount - Delay ) > StartTime ){
				startTime := 0 
				if( windows.Length() ){
					count--
					Gui, % windows[ 1 ] ":Destroy"
					windows.Remove( 1 )
				}
		}
	}
	;~ sleep, 500
	for k , v in windows	{
		Gui, % windows[ k ] ":Destroy"
	}
	Gui, t:Destroy
	KeyWait, g
	return
;}	
;********************
;********************
;********************
;When the color is found it runs this code.
Action_Function_1( x , y , move := 0 ){ ;<--- You can "pass" as many arguments as you need to. In this example I am just passing the x and y values for where the color was found.
	
	MouseMove, x, y 							;example of moving the cursor.
	;~ Sleep, 500			
	;********************
	;This is the action you asked for.
	;~ send, { Space, Down } 					;hold the space key down
	;~ sleep, 30								;wait a fraction of a second
	;~ Send, % "{ Click , " x " , " y " }"		;send a click
	;~ sleep, 30								;wait a fraction of a second
	;~ send, { Space, Up }						;release the space key.
	;~ sleep, 30								;wait a fraction of a second
	;********************
	
	return 1
	
}
;********************
mamo691
Posts: 41
Joined: 07 Jan 2024, 12:40

Re: Find color closest to cursor and click

12 Apr 2024, 20:57

@Hellbent Hey man sorry for answering late. I have tried to change the code you suggested me to make it so that the mask is disabled so the black squares dont pop up, and, fix the inaccurate problem I face when I work with smaller targets. Let me show you the vid : https://gyazo.com/3b7b4426e5049006be0358ca340bd119

I want to send space down while i hold g and so the script works while doing space down and when i stop holding g the script will ofcourse stop working and it will stop sending space down and so send space up. not the way it is as of right now where it sends spacedown and click and space up each time it detects the colour. I couldnt explain my self very well so sorry I apologise for being this stupid. But yeah this is what I want. I would greatly appreciate if you could help me out here!

So basically can you make it work more accurately with much smaller targets, and also make a option to remove mask because my stupid head cant find the 3-4 lines of code that you mentioned here :
- If you don't need a mask you can comment out the 3-4 lines of code that handle displaying the block windows.

And also help me out with the keybinds please?

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Descolada, Google [Bot], IfThenElse, lechat, LuckyJoe and 267 guests