2016-11-23 125 views
3

我在一个机器人工作的网络游戏。登录时,有多个服务器必须从中选择。每台服务器在服务器名称旁边都有一个“在线”/“离线”标识符。即使有多个在线服务器,机器人也只会选择其中一个,每次都是同一个。这有什么奇怪的是,其他人都不应先找到它为此应该得到点击的一个。Sikuli - 如何循环的findAll匹配

我想调整我的代码,这样我可以找到所有的“在线”实例,并选择一个。如果那个连接失败,我希望它通过菜单返回并尝试下一个潜在的在线服务器。当一台服务器无法连接或服务器连接丢失,它可以追溯到与服务器连接丢失弹出主菜单。以下是我正在使用的代码。逻辑基本上是检查任何问题,如失去服务器连接或死亡,其实是想打前修复这些问题。

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) 我试了一下尤金■在这个环节说,但是当我输入他的代码和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.) 
+0

你可以请分享导致错误和错误本身的代码(当试图找到多个匹配)? –

+0

@EugeneS在第1行我有此 DEF returnImageCount( “客服OnLineServer-7.png”): ,它是在第21栏 返回此错误 [错误]脚本无题停止了与误差在第1行[error] SyntaxError('输入'没有可行的替代方案''OnlineServer-7.png'\'',) –

+0

如果将代码包含到您的问题中并进行格式化,将会更容易理解代码。从我现在看到的情况看,您似乎正在尝试为函数定义提供实际的文件名。这不是你如何做到的。函数只定义一段代码,并且可以有一个输入参数/ s,在你的情况下它是图像名称。然后,当你使用这个功能时,你可以提供一个实际的图像名称。 –

回答

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 

注意

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

+0

我不知道:但是我正在阅读它。我无法理解“结果结果”中的“结果”: –

+0

'for'只是一个循环,在这一行中,您遍历由'findAll'找到的一组模式。下一个可用的模式我已经添加了一行'highlight'的例子,它可以帮助你更好地理解逻辑 –

+0

好吧,我只能点击显示在线的服务器,但前几天服务器显示在线并且连接失败,我不知道在连接错误重新加载主菜单之前多久,所以可以告诉它点击1台在线服务器,然后等待游戏加载或无法连接屏幕,如果连接失败,然后点击下一个在线实例?现在它只是找到所有实例,然后点击他们所在的位置,即使在点击第一个服务器后它们消失。 –