Sikuli - 如何循环查找所有匹配项
Sikuli - How to cycle through findAll Matches
我正在为在线游戏开发一个机器人。登录时,我必须 select 从多个服务器。每个服务器在服务器名称旁边都有一个 "online"/"offline" 标识符。即使有多台在线服务器,机器人只会 select 其中一台,而且每次都是一样的。奇怪的是,应该首先找到另一个,因此它应该是被点击的那个。
我想调整我的代码,以便我可以找到所有 "online" 个实例和 select 个实例。如果那个连接失败,那么我希望它通过菜单返回并尝试下一个潜在的在线服务器。当服务器无法连接或服务器连接丢失时,它会返回主菜单并显示服务器连接丢失弹出窗口。下面是我正在使用的代码。逻辑基本上是检查服务器连接丢失或死亡等任何问题,并在实际尝试战斗之前解决这些问题。
BotOn = True
FighterBot = False
def runHotkey(event):
global BotOn
BotOn = False
Env.addHotkey(Key.ESC, KeyModifier.SHIFT, runHotkey)
def BotFighter(event):
global FighterBot
FighterBot = True
Env.addHotkey(Key.PAGE_UP,0, BotFighter)
def BotFighterOff(event):
global FighterBot
FighterBot = False
Env.addHotkey(Key.PAGE_DOWN,0, BotFighterOff)
while BotOn == True:
while FighterBot == True:
if exists("LostServerConnection.png"):
click("LostServerConnection.png")
wait(.5)
if exists("LoginFailed.png"):
click("LoginFailed.png")
wait(.5)
if exists("Login.png"):
click("Login.png")
wait(.5)
if exists("Play.png"):
click("Play.png")
wait(.5)
if exists("OnlineServer.png"):
click("OnlineServer.png")
wait(("AttackButton.png")or("LostServerConnection.png"),FOREVER)
if exists("AttackButton.png"):
#commands for moving to specific location
elif exists("LostServerConnection.png"):
click("LostServerConnection.png")
wait(.5)
if exists("Revive.png"):
click("Revive.png")
waitVanish("Revive.png")
wait("AttackButton.png")
#commands for moving to specific location
else:
#commands for fighting
很抱歉,它写得很粗糙。在我清理它之前,我仍在学习并试图解决这个问题。
我的理想结果是拥有一个功能,该功能将检查有多少服务器在线,为它们创建索引,并能够在尝试登录实际工作的服务器时循环访问该索引。
(Sikuli Check multiple of the same images on screen)
我尝试了 Eugene S 在这个 link 中所说的内容,但是当我在他的 "image" 代码段中输入图像时,Sikuli 在第一行出错:
Edit1:我重新阅读了一些我遗漏的重要信息并修复了代码。它现在不会出错,但它实际上并没有点击任何东西。我确定我遗漏了一些东西,所以在此期间我会继续研究这个问题。
(谢谢 EugeneS)
def returnImageCount(image):
count = 0
for i in findAll(image):
count += 1
return count
imageCount = returnImageCount("OnlineServer.png")
if imageCount == 1:
click(buttonX.image)
elif imageCount == 2:
click(buttonY.image)
else:
pass
Edit2:我已将下面的代码更新为我正在使用的当前代码。它似乎更接近我正在寻找的东西。但是现在它找到所有匹配项,然后单击每个匹配项,即使它从加载它单击的第一个匹配项时消失了。我希望能够执行我在评论中添加的内容。
(谢谢 EugeneS)
wait(5)
OnlineServers = findAll(Pattern("OnlineServer.png").exact())
for Server in OnlineServers:
Server.click()#(only click the first match)
#wait for game to load OR server connection failed(wait as long as it takes)
#if game load
#proceed to standard actions
#elif server connection failed
#log in
#retry logic with next match in list
#(after it finishes going through all possible matches and fails each one, I want it to try again from the first match and go through the cycle again. So if there is only 1 match I want it to just keep trying that one.)
我不知道你的游戏逻辑,但如果你需要使用多种模式,你可以按如下方式进行:
找到它们并存储在某个列表中:
resultsList = findAll("YOUR_FILE_NAME.png")
然后对每个找到的模式执行您需要的操作
for result in resultsList:
result.highlight(1)
#DO WHAT YOU NEED
作为替代方案,您可以只使用列表中的第一项,并在每次需要下一项时将其删除:
NEXT_PATTERN = results.pop(0)
您必须考虑一个对您有意义的策略,并使用我提到的概念来实施它。恕我直言,您应该将所有主要任务分成块,然后构建您的主要逻辑。例如,您可以实现如下功能:
def waitForGameToLoad():
# Wait sufficienttime and verify that the game has been actually successfully started
def isGameLoaded():
# Just and exmaple of another function that can be used internally inside waitForGameToLoad
def getNextAvailableServer():
# Get next available server from a list that you have previously created
因此,您可以以更容易理解的方式构建主要逻辑块,例如:
availableServersList = getAvailableServers() # getAvailableServers is a function that you will have to implement yourself
while True:
connectServer(availableServersList)
if connected():
break
注意
我上面描述的只是关于如何实现主要逻辑的一般建议。您不需要直接遵循它。尝试创建对您有意义的功能,然后一起使用它们来构建逻辑流程。
我正在为在线游戏开发一个机器人。登录时,我必须 select 从多个服务器。每个服务器在服务器名称旁边都有一个 "online"/"offline" 标识符。即使有多台在线服务器,机器人只会 select 其中一台,而且每次都是一样的。奇怪的是,应该首先找到另一个,因此它应该是被点击的那个。
我想调整我的代码,以便我可以找到所有 "online" 个实例和 select 个实例。如果那个连接失败,那么我希望它通过菜单返回并尝试下一个潜在的在线服务器。当服务器无法连接或服务器连接丢失时,它会返回主菜单并显示服务器连接丢失弹出窗口。下面是我正在使用的代码。逻辑基本上是检查服务器连接丢失或死亡等任何问题,并在实际尝试战斗之前解决这些问题。
BotOn = True
FighterBot = False
def runHotkey(event):
global BotOn
BotOn = False
Env.addHotkey(Key.ESC, KeyModifier.SHIFT, runHotkey)
def BotFighter(event):
global FighterBot
FighterBot = True
Env.addHotkey(Key.PAGE_UP,0, BotFighter)
def BotFighterOff(event):
global FighterBot
FighterBot = False
Env.addHotkey(Key.PAGE_DOWN,0, BotFighterOff)
while BotOn == True:
while FighterBot == True:
if exists("LostServerConnection.png"):
click("LostServerConnection.png")
wait(.5)
if exists("LoginFailed.png"):
click("LoginFailed.png")
wait(.5)
if exists("Login.png"):
click("Login.png")
wait(.5)
if exists("Play.png"):
click("Play.png")
wait(.5)
if exists("OnlineServer.png"):
click("OnlineServer.png")
wait(("AttackButton.png")or("LostServerConnection.png"),FOREVER)
if exists("AttackButton.png"):
#commands for moving to specific location
elif exists("LostServerConnection.png"):
click("LostServerConnection.png")
wait(.5)
if exists("Revive.png"):
click("Revive.png")
waitVanish("Revive.png")
wait("AttackButton.png")
#commands for moving to specific location
else:
#commands for fighting
很抱歉,它写得很粗糙。在我清理它之前,我仍在学习并试图解决这个问题。
我的理想结果是拥有一个功能,该功能将检查有多少服务器在线,为它们创建索引,并能够在尝试登录实际工作的服务器时循环访问该索引。
(Sikuli Check multiple of the same images on screen) 我尝试了 Eugene S 在这个 link 中所说的内容,但是当我在他的 "image" 代码段中输入图像时,Sikuli 在第一行出错:
Edit1:我重新阅读了一些我遗漏的重要信息并修复了代码。它现在不会出错,但它实际上并没有点击任何东西。我确定我遗漏了一些东西,所以在此期间我会继续研究这个问题。 (谢谢 EugeneS)
def returnImageCount(image):
count = 0
for i in findAll(image):
count += 1
return count
imageCount = returnImageCount("OnlineServer.png")
if imageCount == 1:
click(buttonX.image)
elif imageCount == 2:
click(buttonY.image)
else:
pass
Edit2:我已将下面的代码更新为我正在使用的当前代码。它似乎更接近我正在寻找的东西。但是现在它找到所有匹配项,然后单击每个匹配项,即使它从加载它单击的第一个匹配项时消失了。我希望能够执行我在评论中添加的内容。 (谢谢 EugeneS)
wait(5)
OnlineServers = findAll(Pattern("OnlineServer.png").exact())
for Server in OnlineServers:
Server.click()#(only click the first match)
#wait for game to load OR server connection failed(wait as long as it takes)
#if game load
#proceed to standard actions
#elif server connection failed
#log in
#retry logic with next match in list
#(after it finishes going through all possible matches and fails each one, I want it to try again from the first match and go through the cycle again. So if there is only 1 match I want it to just keep trying that one.)
我不知道你的游戏逻辑,但如果你需要使用多种模式,你可以按如下方式进行:
找到它们并存储在某个列表中:
resultsList = findAll("YOUR_FILE_NAME.png")
然后对每个找到的模式执行您需要的操作
for result in resultsList:
result.highlight(1)
#DO WHAT YOU NEED
作为替代方案,您可以只使用列表中的第一项,并在每次需要下一项时将其删除:
NEXT_PATTERN = results.pop(0)
您必须考虑一个对您有意义的策略,并使用我提到的概念来实施它。恕我直言,您应该将所有主要任务分成块,然后构建您的主要逻辑。例如,您可以实现如下功能:
def waitForGameToLoad():
# Wait sufficienttime and verify that the game has been actually successfully started
def isGameLoaded():
# Just and exmaple of another function that can be used internally inside waitForGameToLoad
def getNextAvailableServer():
# Get next available server from a list that you have previously created
因此,您可以以更容易理解的方式构建主要逻辑块,例如:
availableServersList = getAvailableServers() # getAvailableServers is a function that you will have to implement yourself
while True:
connectServer(availableServersList)
if connected():
break
注意
我上面描述的只是关于如何实现主要逻辑的一般建议。您不需要直接遵循它。尝试创建对您有意义的功能,然后一起使用它们来构建逻辑流程。