AHK自定义函数无法访问外部变量导致if判断失效求解决方案
原因分析
AutoHotkey v1 中函数默认使用独立的局部作用域,未显式声明的变量会被识别为函数内部的局部变量,无法读取/修改外部全局作用域的变量值,你遇到的if判断不生效就是test()函数内的number实际为未赋值的局部变量,永远不会匹配1/2/3/4的条件。
另外你现有代码的4个number判断为并列执行逻辑,当第一个判断执行后修改了number值,后续的判断也会依次触发,会导致单次timer周期内连续执行4次CheckMap操作,不符合逻辑预期。
解决方案
最推荐:函数内显式声明需要访问的全局变量
只需要在test()函数开头添加global number声明,告诉函数这个变量是全局作用域的变量即可,该方式作用域控制最精准,不会产生额外的变量污染。
修改后的test函数示例:
test(){ global number ; 显式声明使用全局的number变量 if WinActive("program") { ImageSearch, foundX, foundY, 2000, 0, 2560, 1440, target.png if (ErrorLevel = 1) { ; 把并列if改成else if,单次仅执行一个分支 if (number = 1) { CheckMap("star.png") number := 2 } else if (number = 2) { CheckMap("like.png") number := 3 } else if (number = 3) { CheckMap("question.png") number := 4 } else if (number = 4) { CheckMap("cross.png") number := 1 } } } }
其他可选方案
- 方案2:在test()函数开头直接写不带变量名的
global,声明该函数内所有未定义变量默认使用全局作用域,适合函数需要访问多个全局变量的场景。 - 方案3:定义number变量时声明为超级全局变量,即定义时写
global number := 1,该方式下所有函数都无需单独声明即可访问/修改该变量,适合多个函数都需要操作该变量的场景。
调整后的完整代码
SetTimer, test, 2000 ;I started off with 1000 then worked up to this number to confirm this was happening number := 1 test: test() return test(){ global number if WinActive("program") { ImageSearch, foundX, foundY, 2000, 0, 2560, 1440, target.png if (ErrorLevel = 1) { if (number = 1) { CheckMap("star.png") number := 2 } else if (number = 2) { CheckMap("like.png") number := 3 } else if (number = 3) { CheckMap("question.png") number := 4 } else if (number = 4) { CheckMap("cross.png") number := 1 } } } } CheckMap(x){ ImageSearch, foundX, foundY, 2000, 0, 2560, 1440, %x% if (ErrorLevel = 0) { MouseGetPos, StartX, StartY Click, %foundX%, %foundY% MouseMove, StartX, StartY } } *[:: Suspend Pause, 1 return *]:: ExitApp return
内容的提问来源于stack exchange,提问作者Robakopas
相关产品推荐
相关产品推荐

