AHK PixelSearch Loop - autohotkey

I'm trying to get my AHK Script to Work.
Basically i want to find a row of x Pixels with the Color 0x26FDFD (BGR). But i don't know the AHK Scripting language well wnough to think about a smart, clean and easy way to program that loop, that the starting point will be modified based on the last found coordinates.
However, here's what i got so far:
SysGet, VirtualWidth, 78
SysGet, VirtualHeight, 79
;Farbe nach der gesucht wird:
ColorVar := 0x26FDFD
i:=0
while i < 10
{
PixelSearch, FoundX, FoundY, 0, 0, VirtualWidth, VirtualHeight, %ColorVar%, 3, Fast
if (ErrorLevel = 2)
{
MsgBox Could not conduct the search.
return
}
else if (ErrorLevel = 1)
{
MsgBox Color could not be found on the screen.
return
}
else
{
MouseMove, %FoundX%, %FoundY%
MsgBox Found a Pixel at %FoundX%x%FoundY%.
;return
}
i++
}
Kinda stupid and basic question, but somehow i can't figure it out.

I just needed to store the X and Y coordinates at the end of each loop, then set the new startpoint accordingly.
here's the code:
i:=0
while i < 5
{
PixelSearch, FoundX, FoundY, startX%A_Index%, startY%A_Index%, VirtualWidth, VirtualHeight, %ColorVar%, 3, Fast
Switch ErrorLevel
{
Case 1:
MsgBox Website ueberpruefen!
return
Case 2:
MsgBox Makro ueberpruefen!
return
Default:
MouseMove, %FoundX%, %FoundY%
;MsgBox Found a Pixel at %FoundX%x%FoundY%.
nextLoop := A_Index + 1
startX%nextLoop% := FoundX + 1
startY%nextLoop% := FoundY
}
i++
}
;msgbox % "found 5 matches!, first at: " startX2 "x" startY2
return

Related

Moving the cursor to a specified position as soon as it touches right edge of screen using autohotkey?

I have written code to change mouse position when it touches the left edge of screen
sysget, var_, monitorworkarea
gui, color, 0x000000
gui, +alwaysontop +toolwindow -caption
gui, show, w1 h%var_bottom% x0 y0, left_win
winset, transparent, 1, left_win
onmessage(0x200, "edge")
return
edge()
{
static countdown := 0
if (countdown = 0)
{
settimer, check, -100
countdown := 1
}
return
check:
{
mousegetpos, , , win
wingettitle, title, ahk_id %win%
if (title = "left_win")
{
MouseMove, 960, 300, 0
}
countdown := 0
}
return
}
but it doesn't work if I replace left with right for right edge of screen How do I fix this ?
Try this
#Persistent
SetTimer, check, -100
return
check(){
If edge("left")
{
MouseMove, 960, 300, 0
Send #x
}
else if edge("right")
{
MouseMove, 960, 300, 0
Run Notepad
}
; ...
SetTimer, check, -100
}
edge(pos){
SysGet, VirtualWidth, 78
SysGet, VirtualHeight, 79
T := 10
CoordMode, Mouse, Screen
MouseGetPos, mX, mY
left := (mX < T)
top := (mY < T)
right := (mX > VirtualWidth - T)
bottom := (mY > VirtualHeight - T)
If (pos = "left")
return left
else if (pos = "top")
return top
else if (pos = "right")
return right
else if (pos = "bottom")
return bottom
}

How to Teleport a mouse (not MouseMove) in ahk?

I am trying to play games using a remote desktop software called rustdesk and I have created a script to move mouse 360 degrees in horizontal manner but as soon as the mouse goes from left to right the character in the game also moves so how to MoveMouse without seeing those changes in rustdesk.
This is the code:
#Persistent
SetTimer, check, -100
return
check(){
If edge("left")
{
MouseMove, 1718, 490, 0
}
else if edge("right")
{
MouseMove, 0, 490, 0
}
; ...
SetTimer, check, -100
}
edge(pos){
SysGet, VirtualWidth, 78
SysGet, VirtualHeight, 79
T := 10
CoordMode, Mouse, Screen
MouseGetPos, mX, mY
left := (mX < T)
top := (mY < T)
right := (mX > VirtualWidth - T)
bottom := (mY > VirtualHeight - T)
If (pos = "left")
return left
else if (pos = "top")
return top
else if (pos = "right")
return right
else if (pos = "bottom")
return bottom
}
I tried using BlockInput but it completely stops the mouse.

Why when I run application it just skip some ifs

As I said text that is bolded doesn't work, it just skip it (it worked without those ifs) could you help me? Please, I'm doing that few hours but it still doesn't work. I tried to add this if not in this loop and it worked, please give me a hand, I spent so much time
on it ;(
Gui, Add, CheckBox, x405 y317 w15 h15 vwyrzucaniediax gZapisz,
Gui, Show, h500 w800, Skrypt Na Kopanie
Return
Zapisz:
Gui, Submit , NoHide
return
F8::
WinMove, Minecraft, , , , 1280, 720
sleep 1000
Loop
{
if poziome
{
}
if pionowe
{
}
Checker()
}
Checker()
{
x := 503
y := 385
l := 0
i := 0
Send e
loop, 27{
if(i = 9){
i := 0
l++
}
Sleep 100
MouseMove, x +36*i, y + 36*l
**if wyrzucaniediax // all strong text is just skipped idk why
{
Dropdiax()
}
**
i++
}
Send e
Sleep 50
}
dropdiax(){
diaxcolor := 0x80ĄFFE
color:= getColor()
if(color == diaxcolor){
Send {LCtrl down}
Send q
Sleep 50
Send {LCtrl up}
}
}```
Your wyrzucaniediax variable (maybe you could use better variable names when asking for help?) isn't defined in that function's scope.
To tell the function you're using a variable from outside of its scope, you can use the Global keyword.
Checker()
{
global wyrzucaniediax
x := 503
y := 385
l := 0

Passing an Array through Function Then Looping

I am writing a function that would loop imagesearch but I am having trouble figuring out how to pass a dynamic variable with the options allowed with Arrays (Such as Array0 which retrieves the total count of records in array, and Array%A_Index% which when used with a Loop displays each name as it goes through the list)
arrowList = C:\AHK\LeftArrow.png|C:\AHK\LeftArrow1.png|C:\AHK\GreenLeftArrow.png
StringSplit, arrowArray, arrowList, |
buildList = C:\AHK\build1.png|C:\AHK\build2.png|C:\AHK\build3.png|C:\AHK\build4.png|C:\AHK\build5.png
StringSplit, buildArray, buildList, |
SearchArray("arrowArray","buildArray")
SearchArray(ByRef x, ByRef y)
{
Loop, %x%
{
x2get := %xA_Index%
ImageSearch, imageX, imageY, 0, 0, A_ScreenWidth, A_ScreenHeight, *25 %x2get%
tooltip, searching for %x2get% , 0, 0
If ErrorLevel = 0
{
Loop, % y%0%
{
y2get := % y%A_Index%
ImageSearch, imageX, imageY, 0, 0, A_ScreenWidth, A_ScreenHeight, *25 %y2get%
tooltip, searching for %y2get% , 0, 0
If ErrorLevel = 0
{
MouseClick, Left, imageX, imageY,
Sleep 1000
}
}
}
}
}
You have some problems with how you're calling the variables. You're not actually using "real" arrays there, you're using what's called "pseudo-arrays". You can read about them in the documentation, here.
They're an old way AHK handled arrays, and I strongly suggest you try to move over to using "real" arrays in AHK. You should also update your version of AHK to the latest if you haven't already - http://ahkscript.org/download/.
I changed how the script called some variables, and it should work now, try this, note I've commented the lines I changed:
arrowList = C:\AHK\LeftArrow.png|C:\AHK\LeftArrow1.png|C:\AHK\GreenLeftArrow.png
StringSplit, arrowArray, arrowList, |
buildList = C:\AHK\build1.png|C:\AHK\build2.png|C:\AHK\build3.png|C:\AHK\build4.png|C:\AHK\build5.png
StringSplit, buildArray, buildList, |
SearchArray("arrowArray", "buildArray")
SearchArray(ByRef x, ByRef y)
{
Loop, % %x%0 ; Changed this line
{
x2get := %x% A_Index ; Changed this line
ImageSearch, imageX, imageY, 0, 0, %A_ScreenWidth%, %A_ScreenHeight%, *25 %x2get% ; Changed this line
tooltip, searching for %x2get% , 0, 0
If ErrorLevel = 0
{
Loop, % %y%0 ; Changed this line
{
y2get := % %y% A_Index ; Changed this line
ImageSearch, imageX, imageY, 0, 0, %A_ScreenWidth%, %A_ScreenHeight%, *25 %y2get% ; Changed this line
tooltip, searching for %y2get% , 0, 0
If ErrorLevel = 0
{
MouseClick, Left, %imageX%, %imageY% ; Changed this line
Sleep 1000
}
}
}
}
}
If you're interested in how a solution using "real" arrays would look, here's an example of that. Just make sure you're running the latest version of AHK before you try it, otherwise it might fail.
arrowList := "C:\AHK\LeftArrow.png|C:\AHK\LeftArrow1.png|C:\AHK\GreenLeftArrow.png"
arrowArray := StrSplit(arrowList, "|")
buildList := "C:\AHK\build1.png|C:\AHK\build2.png|C:\AHK\build3.png|C:\AHK\build4.png|C:\AHK\build5.png"
buildArray := StrSplit(buildList, "|")
SearchArray(arrowArray, buildArray)
SearchArray(firstArray, secondArray) {
; Iterate through the first array
for outerIndex, outerValue in firstArray {
; outerIndex = Index of the current element; 1, 2, etc...
; outerValue = The value of the string at that index
Tooltip, Searching for %outerValue%, 0, 0
ImageSearch, imageX, imageY, 0, 0, %A_ScreenWidth%, %A_ScreenHeight%, *25 %outerValue%
if (ErrorLevel = 0) {
; Iterate through the second array
for innerIndex, innerValue in secondArray {
; innerIndex = Index of the current element; 1, 2, etc...
; innerValue = The value of the string at that index
Tooltip, Searching for %innerValue%, 0, 0
ImageSearch, imageX, imageY, 0, 0, %A_ScreenWidth%, %A_ScreenHeight%, *25 %innerValue%
if (ErrorLevel = 0) {
MouseClick, Left, %imageX%, %imageY%
Sleep, 1000
}
}
}
}
}

Autohotkey: How to program to walk in 2D game

I'm writing a macro for a 2D game. The coordinates for the character are given, in (x,y). There are obstacles in the game, so I need to program in a way that the character moves around it.
So I've written a program that reads the memory of x and y coordinates of the game. Then I wrote a function that moves the character to a desired position. The logic is: if x coordinate is less than the desired position, keep moving right, and vice versa. Then, if y coordinate is less than the desired position, keep moving up, and vice versa.
However, because of the obstacles, I have to manually give the coordinates to move to. For example, if I was at (1,1), and told the character to move to (5,5), there might be an obstacle at (3,1) and the character will get stuck. So I'll tell it to move to (1,3) first, then move to (5,3), then (5,5).
I'm just confused on how to SEQUENTIALLY tell the character to move. AFTER I move to (1,3), move to (5,3), then (5,5).
This is what I have:
f1::
WinGetTitle, ai, A
curX := ReadMemory(0x10F6A7D0, ai)
curY := ReadMemory(0x10F6A7D4, ai)
MoveTo(21,13)
if(curX == 21 && curY == 13){
MoveTo(21,28)
}
return
q::
Pause
return
ReadMemory(MADDRESS,PROGRAM)
{
winget, pid, PID, %PROGRAM%
VarSetCapacity(MVALUE,4,0)
ProcessHandle := DllCall("OpenProcess", "Int", 24, "Char", 0, "UInt", pid, "UInt")
DllCall("ReadProcessMemory","UInt",ProcessHandle,"UInt",MADDRESS,"Str",MVALUE,"UInt",4,"UInt *",0)
Loop 4
result += *(&MVALUE + A_Index-1) << 8*(A_Index-1)
return, result
}
MoveTo(targetX,targetY)
{
xadd = 0x10F6A7D0
yadd = 0x10F6A7D4
WinGetTitle, ai, A
Loop{
curX:= ReadMemory(xadd,ai)
curY:= ReadMemory(yadd,ai)
if(curX < targetX){
ControlSend,, {Right}, %ai%
}
else if(curX > targetX){
ControlSend,, {Left}, %ai%
}
else if(curY < targetY){
ControlSend,, {Down}, %ai%
}
else if(curY > targetY){
ControlSend,, {Up}, %ai%
}
Sleep, 30
Okay, so I solved my problem. I just had to make a while-loop in the MoveTo function and terminate it once I reach the position.
MoveTo(targetX,targetY)
{
xadd = 0x10F6A7D0
yadd = 0x10F6A7D4
WinGetTitle, ai, A
isThere := 1
while(isThere = 1){
curX:= ReadMemory(xadd,ai)
curY:= ReadMemory(yadd,ai)
if(curX < targetX){
ControlSend,, {Right}, %ai%
}
else if(curX > targetX){
ControlSend,, {Left}, %ai%
}
else if(curY < targetY){
ControlSend,, {Down}, %ai%
}
else if(curY > targetY){
ControlSend,, {Up}, %ai%
}
if(curX = targetX && curY = targetY){
isThere = 0
}
Sleep, 30