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

注意

我上面描述的只是关于如何实现主要逻辑的一般建议。您不需要直接遵循它。尝试创建对您有意义的功能,然后一起使用它们来构建逻辑流程。