Почему pyautogui.locateOnScreen() находит мое изображение только на первой итерации цикла?Python

Программы на Python
Ответить
Anonymous
 Почему pyautogui.locateOnScreen() находит мое изображение только на первой итерации цикла?

Сообщение Anonymous »

Я пытаюсь создать сценарий автоматического кликера для старой игры, в котором игрок собирает статистику при создании персонажа. Я хочу прочитать экран игры на наличие минимального балла и, если он не найден, нажать «перевернуть», а затем снова запустить проверку. У меня в каталоге IDE сохранены снимки экрана с минимальным счетом (8 цифр) и кнопкой повторного просмотра с экрана выбора персонажа. Идея состоит в том, чтобы использовать функцию pyautogui.locateOnScreen() для проверки минимального балла в области экрана, которую я определяю путем сопоставления с сохраненным изображением минимального балла. Если он недостаточно высок, курсор должен нажать кнопку повторного прокрутки, которая расположена так же, как при проверке снимка экрана с кнопкой повторного прокрутки. На данный момент у меня есть следующий код:

Код: Выделить всё

import win32gui
import win32con
import sys
import pyautogui
import time

game_window = "Baldur's Gate - Enhanced Edition - v2.6.6.0"

#find game window and make foreground - otherwise exit script
def find_window_and_foreground(target):
hwnd = win32gui.FindWindow(None, game_window)

if hwnd > 0:
win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
win32gui.SetForegroundWindow(hwnd)
print("game set to foreground")
else:
print("Baldur's Gate not running - exiting program")
sys.exit()

time.sleep(1)

#pixel location of leading digit in total score on screen in game - x,y,width,height
search_range = (977,1108,108,40)

#look for a minimum score of 80 and return true otherwise print low roll message and return false
#8-10s.png is a clipped screenshot of an 8 as the leading digit in total score in-game
def check_score():
try:
location_of_score = pyautogui.locateOnScreen('8-10s.png', confidence=0.8, region=search_range)
pyautogui.click(location_of_score)#just for testing
return True
except pyautogui.ImageNotFoundException:
print('score is not in the 80s')
return False

find_window_and_foreground(game_window)

#look for reroll button in game - exit if not found
try:
reroll_location = pyautogui.locateOnScreen('reroll.png', confidence=0.8)
except pyautogui.ImageNotFoundException:
print("reroll button not found - exiting program")
sys.exit()

while True:
if check_score():
print('rolled in the 80s')
sys.exit()
else:
pyautogui.click(reroll_location)
print('rerolled')
time.sleep(2)
Когда я запускаю код, окно игры обнаруживается и правильно становится на передний план. Если случайный бросок, с которого начинается игра, удовлетворяет критерию поиска (выпавший в 80-х годах), сценарий ведет себя так, как ожидалось (печатает сообщение «выпало в 80-х» и нажимает на счет). Однако, если стартовый счет не удовлетворяет критерию поиска, сценарий постоянно печатает «счет не в 80-х», «перебрасывается» и нажимает кнопку переброса, даже если новый счет после переброса удовлетворяет требованиям. Похоже, что pyautogui.locateOnScreen() ведет себя так, как ожидалось, на первой итерации цикла while True, но неожиданно на последующих итерациях. Я не понимаю, почему, и отладка проблематична, потому что игра сворачивается, если я нажимаю на любой другой экран, даже на других мониторах.
Я прочитал несколько сообщений, в которых говорилось, что функцияlocateOnScreen() может занять некоторое время (я думаю, в документации указано 2-5 секунд или около того), но я не думаю, что это причина неожиданного поведения, потому что искомое изображение и поле поиска довольно малы, и у меня есть 2 вторая задержка в скрипте как есть (я также тестировал ее до 5 секунд с таким же поведением). Кроме того, как я уже сказал выше, если начальное значение общего балла превышает 80, программа работает правильно (это также тот случай, если я вручную повторно увеличиваю балл до 80 или выше, а затем запускаю скрипт).
В других сообщениях оlocateOnScreen() также упоминается игра со значением достоверности в качестве аргумента. Я установил значение 0,8 и получил приличные результаты. Иногда мне все еще не хватает кнопки перемотки, но после нескольких попыток она работает правильно. Я также не думаю, что это является причиной наблюдаемого поведения, поскольку результаты общего балла при первом проходе цикла while True близки к 100 %, в то время как последующие проходы никогда не давали совпадений, даже после нескольких минут повтора.

Действительно кажется, что я могу получить значение True для check_score() только при первом проходе цикла while True, в то время как каждая последующая итерация дает False возвращаемое значение. Мои познания в программировании очень ограничены, но я смутно припоминаю, что при чтении входных данных на Java было хорошей практикой создавать новые экземпляры сканера, потому что он использовал буфер, который мог дать неожиданные результаты, если бы содержимое не было «сброшено» путем создания нового экземпляра. Здесь происходит что-то подобное?
Будем благодарны за любую помощь.
Окружающая среда:

ОС Windows 10 22H2, сборка 19045.6466

python 3.9.13

PyCharm 2022.3.3 (Community Edition) Сборка #PC-223.8836.43
Помимо импортированных пакетов, аргумент доверия для pyautogui.locateOnScreen() использует opencv-python.

Подробнее здесь: https://stackoverflow.com/questions/798 ... eration-of
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»