Sikuli - 如何循环查找所有匹配

时间:2016-11-23 17:54:53

标签: python automation sikuli

我正在为在线游戏开发机器人。登录时,我必须选择多个服务器。每个服务器在服务器名称旁边都有一个“在线”/“离线”标识符。即使有多个在线服务器,机器人也只会选择其中一个,每次都选择相同的服务器。而奇怪的是,应该首先找到另一个应该被点击的人。

我想调整我的代码,以便找到所有“在线”实例并选择一个。如果那个无法连接,那么我希望它返回菜单并尝试下一个潜在的在线服务器。当服务器连接失败或服务器连接丢失时,它会返回主菜单,并显示Server Connection Lost弹出窗口。下面是我正在使用的代码。逻辑基本上是检查服务器连接丢失或死亡等问题,并在实际尝试战斗之前解决这些问题。

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在这个链接中所说的,但是当我在他的代码的“图像”中输入图像时,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.)

1 个答案:

答案 0 :(得分:0)

我不了解您的游戏逻辑,但如果您需要处理多种模式,可以按以下方式执行此操作:

找到它们并存储在一些列表中:

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

注意

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