Что нового

[Автоматизация] оптимизация кода по поиску пикселей и клики на них

Сообщения
137
Репутация
-2
Добрый день,

Хотел бы попросить оптимизировать мой код для игры. Собственно, задача сводится к 4 вызовам функции _PixelGetArray Задача скрипта:
1) находим все уникальные пиксели для иконок золота (0x8A7D70) и неактивных иконок зданий ресурсов (0xBBAA77) и кликаем на каждый пиксель, который находим.При клике на пиксель золотой иконки (0x8A7D70) - получаем золото в банк и иконка исчезает на 5 минут, затем снова появляется, таких иконок порядка 30 штук по всему экрану.
2) при клике на пиксель иконки неактивного здания ресурсов (0xBBAA77) , открывается окно, в котором нам нужно кликнуть в определённом квадрате области экрана. После клика окошко исчезает и иконка на здании тоже пропадает на минут 5 пока ресурс создаётся.
3 ) над зданиями ресурсов появляется икона готового продукта и нам снова нужно на него кликнуть (зданий штук 15 также по всему экрану). После клика ресурс собирается и снова появляется иконка неактивного здания ресурсов (0xBBAA77) и мы повторяем все процедуры.
Упростил для наглядности как мог:
Код:
;------------------------------------ код
$X = 100
$Y = 50
$Width = 1100
$Height = 570
; иcкомый цвет пикселя
$GColor = 0xFFEE77 
$MColor = 0xBB9966
$okColor = 0xB8712B
$HColor = 0xB95102 

;---------------------------------------------------------- код

While 1
                ; код
		; I =================поиск всех пикселей цвета 0xFFEE77 и клики по ним
                ;по задумке пока есть хоть 1 пиксель цвета  0xFFEE77 на экране скрипт не должен дальше переходить к поиску цвета 0xBB9966 
		$aP1 = _PixelGetArray($X, $Y, $Width, $Height, 0xFFEE77, $hControl, True)
                 ; код

		;II ===поиск каждого пикселя цвета 0xBB9966 клик по нему,поиск ближайшего пикселя 0xB8712B и клик по нему

		; по задумке пока есть хоть один пиксель цвета 0xBB9966 на экране скрипт не должен переходить к поиску цвета 0xB95102
		$aP2 = _PixelGetArray($X, $Y, $Width, $Height,0xBB9966, $hControl, True)
	        ; код
                ;после клика на 0xBB9966 открывается окно, где будем искать первый пиксель цвета 0xB8712B и кликаем на него
		$aP3 = _PixelGetArray(245, 295, 140, 175, 0xB8712B, $hControl, True)
		 ; код

		;III ==================поиск всех пикселей цвета 0xB95102 с Shade 5 и клики по ним

                ; снова пока на экране есть пиксели с цветом 0xB95102 не переходим в начало для поиска  всех пикселей цвета 0xFFEE77
		$aP4 = _Hummer($X, $Y, $Width, $Height, 0xB95102, 5, $hControl, True)
		 ; код

		;=============================================== 
	

WEnd
;---------------------------------------------------------- код

Если искать цвет по отдельности - всё хорошо работает, а вот если так как у меня выше - вылетает после нахождения первого пикселя и клика по нему. Посоветуйте, пожалуйста, как мне это "подружить", чтоб всё было в одном коде?
 
Автор
D
Сообщения
137
Репутация
-2
OffTopic:
И ещё вопрос - можно ли удалять свои темы и если Да, то как?
 

Dm666

Осваивающий
Сообщения
221
Репутация
48
Что в _PixelGetArray и с какой ошибкой падает?
 
Автор
D
Сообщения
137
Репутация
-2
Не совсем понял вопрос про что в _PixelGetArray, вроде ж указал все постоянные. Ошибку никакую не выдаёт, просто выходит из скрипта и всё. Я оптимизировал чуть код и оно вылетать перестало:

Код:
;------------------------------------ код
$X = 100
$Y = 50
$Width = 1100
$Height = 570
; иcкомый цвет пикселя
$GColor = 0xFFEE77
$MColor = 0xBB9966
$okColor = 0xB8712B
$HColor = 0xB95102

;---------------------------------------------------------- код
While 1
                ; код
        ; I =================поиск всех пикселей цвета 0xFFEE77 и клики по ним
                ;по задумке пока есть хоть 1 пиксель цвета  0xFFEE77 на экране скрипт не должен дальше переходить к поиску цвета 0xBB9966

			Call("_aP1")

        ;II ===поиск каждого пикселя цвета 0xBB9966 клик по нему,поиск ближайшего пикселя 0xB8712B и клик по нему

        ; по задумке пока есть хоть один пиксель цвета 0xBB9966 на экране скрипт не должен переходить к поиску цвета 0xB95102

           Call("_aP2")
                ;после клика на 0xBB9966 открывается окно, где будем искать первый пиксель цвета 0xB8712B и кликаем на него


        ;III ==================поиск всех пикселей цвета 0xB95102 с Shade 5 и клики по ним

                ; снова пока на экране есть пиксели с цветом 0xB95102 не переходим в начало для поиска  всех пикселей цвета 0xFFEE77

        	Call("_aP4")

        ;===============================================


WEnd
;---------------------------------------------------------- код

Func _aP1()

		$aP1 = _PixelGetArray($X, $Y, $Width, $Height, 0xFFEE77, $hControl, True)

		; кликаем по координ
		For $i = 1 To $aP1[0][0] ;Количество строк в массиве (n)

			Sleep(500)
			$iClick += ControlClick($hWnd, "", $hControl, "left", 1, $aP1[$i][0], $aP1[$i][1] + 60)


		Next


		Sleep(1000)


EndFunc   ;==>_aP1
;-------------------------------
Func _aP2()

		 $aP2 = _PixelGetArray($X, $Y, $Width, $Height,0xBB9966, $hControl, True)

		For $i = 1 To $aP2[0][0] ;Количество строк в массиве (n)

			ControlClick($hWnd, "", $hControl, "left", 1, $aP2[$i][0], $aP2[$i][1] + 35)

		Next

		Sleep(1500)

		$aP3 = _PixelGetArray(245, 295, 140, 175, 0xB8712B, $hControl, True)

		For $i = 1 To $aP3[0][0]

			$iClick += ControlClick($hWnd, "", $hControl, "left", 1, $aP3[$i][0], $aP3[$i][1])

			Sleep(500)

		Next

		Sleep(1000)



EndFunc   ;==>_aP2
;-------------------------------
Func _aP4()

	$aP4 = _Hummer($X, $Y, $Width, $Height, 0xB95102, 5, $hControl, True)
	; кликаем по координ

	For $i = 1 To $aP4[0][0] ;Количество строк в массиве (n)

		 ControlClick($hWnd, "", $hControl, "left", 1, $aP4[$i][0], $aP4[$i][1] + 35)

		Sleep(1000)
	Next
	Sleep(1000)

EndFunc   ;==>_aP4
;-------------------------------


Добавлено:
Сообщение автоматически объединено:

Мне нужно, чтоб выполнялась функция Func _aP1() пока есть пиксели с цветом 0xFFEE77. Всё на что мне хватает идей - это сделать Do и Until:

Код:
;---------------------------------------------------------- код

Func _aP1()
Do
		$aP1 = _PixelGetArray($X, $Y, $Width, $Height, 0xFFEE77, $hControl, True)

		; кликаем по координ
		For $i = 1 To $aP1[0][0] ;Количество строк в массиве (n)

			Sleep(500)
			$iClick += ControlClick($hWnd, "", $hControl, "left", 1, $aP1[$i][0], $aP1[$i][1] + 60)


		Next


		Sleep(1000)
Until $iClick = 25 ; по количеству иконок с нужным пикселем, но как быть если их меньше или вдруг глюкнет и кликнет дважды где-то, получится одна иконка будет пропущена, либо же,если их меньше 25, скрипт будет ждать пока их не станет 25, что тоже не есть хорошо.
;или Until $iClick =$aP1[0][0] но тогда в _PixelGetArray нужно ставить False и получим масштабное нажатие на иконки, чего мне не очень хотелось бы
EndFunc   ;==>_aP1
;-------------------------------
 

Dm666

Осваивающий
Сообщения
221
Репутация
48
Dessan [?]
Не совсем понял вопрос про что в _PixelGetArray, вроде ж указал все постоянные. Ошибку никакую не выдаёт, просто выходит из скрипта и всё. Я оптимизировал чуть код и оно вылетать перестало:
_PixelGetArray - самописная UDF. Так же как и этот ваш _Hummer(). Их содержание - тайна покрытая мраком. Там могли быть ошибки. Ну а раз больше не вылетает - значит порядок.

Dessan [?]
Мне нужно, чтоб выполнялась функция Func _aP1() пока есть пиксели с цветом 0xFFEE77. Всё на что мне хватает идей - это сделать Do и Until:
Нормальное решение. Работает? Ничего не трогай! (с) народная мудрость.
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Dm666
Ответ #19 (под спойлером)

Dessan
если их меньше или вдруг глюкнет
Код:
Func _aP1()
  Do
    ; находим все пиксели
    $aP1 = _PixelGetArray($X, $Y, $Width, $Height, 0xFFEE77, $hControl, False)
    ; завершаем функцию при отсутствии пикселей
    If Not $aP1[0][0] Then Return
    ; кликаем по всем пикселям
    For $i = 1 To $aP1[0][0]
      ControlClick($hWnd, "", $hControl, "left", 1, $aP1[$i][0], $aP1[$i][1] + 60)
      Sleep(1000)
    Next
  Until 0 ; повторяем поиск
EndFunc
 
Автор
D
Сообщения
137
Репутация
-2
Спасибо!
К сожалению, не было времени толком проверить. При первом запуске скрипт начал как положено, а затем всё равно полез кликать на пиксели совсем из другой функции Call. В любом случае условия Until 0 в справке не нашёл и за такую подсказку я очень благодарен.

Ещё хотел уточнить:

Код:
$aP1 = _PixelGetArray($X, $Y, $Width, $Height, 0xFFEE77, $hControl, True) - вызов функции
Func _PixelGetArray($iX, $iY, $iWidth, $iHeight, $iColor, $hWnd = 0, $FirstOnly = False) - сама функции

Так вот значение True/False при вызове функции присваивается самой функции? То есть не важно что стоит в самой функции, главное какое значение True/False при вызове её?
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Dessan
В описании функции могут быть использованы параметры по умолчанию. Если при вызове функции эти параметры не указываются, то будут применены умолчания
Код:
$aP1 = _PixelGetArray($X, $Y, $Width, $Height, 0xFFEE77)
; при таком вызове $hWnd будет равно 0, а $FirstOnly примет значение False

Если при вызове необязательные параметры будут указаны, то параметры по умолчанию будут замены на указанные при вызове, даже если они одинаковы. Другими словами, явно указанные при вызове параметры имеют приоритет над параметрами по умолчанию. Но, если нужно изменить только один параметр, заданный умолчанием, то нужно явно указать и все необязательные перед ним умолчания (при наличии таковых). Например, прописать такие же значения, как и принятые по умолчанию
Код:
$aP1 = _PixelGetArray($X, $Y, $Width, $Height, 0xFFEE77, 0, True)
; для поиска только первого пикселя на всём экране
; меняем последний параметр, но указываем и предпоследний


Примечания по использованию функций
 
Автор
D
Сообщения
137
Репутация
-2
А можно это $aP1 = _PixelGetArray($X, $Y, $Width, $Height, 0xFFEE77, 0, True) приспособить к поиску одновременно двух цветов? То есть у меня на экране может появиться либо кнопка с одним цветом пикселей, либо такая же кнопка, но с другим. И если я буду определять только какой-то один цвет пикселя, то при появлении кнопки с другим цветом - окно так и останется висеть и скрипт не сможет работать дальше.
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Dessan
Если цвет не найден, то элемент $aP1[0][0] будет равен нулю. Если так, то вызываете функцию повторно для другого цвета. И так по кругу, пока какой-нибудь из цветов не будет найден.
 
Автор
D
Сообщения
137
Репутация
-2
Ясно, я думал можно как-то оптимизировать. Что-то типа:

Код:
;-------------------------
Func _aP1()
  Do
    ; находим все пиксели
Switch $aP1[0][0] = 1
Case $Color =  0xFFEE77
    $aP1 = _PixelGetArray($X, $Y, $Width, $Height, $Color, $hControl, True)
       ; кликаем по пикселям
    For $i = 1 To $aP1[0][0]
      ControlClick($hWnd, "", $hControl, "left", 1, $aP1[$i][0], $aP1[$i][1] + 60)
      Sleep(1000)
    Next
Case $Color =  0xFFFFFF
    $aP1 = _PixelGetArray($X, $Y, $Width, $Height, $Color, $hControl, True)
       ; кликаем по пикселям
    For $i = 1 To $aP1[0][0]
      ControlClick($hWnd, "", $hControl, "left", 1, $aP1[$i][0], $aP1[$i][1] + 60)
      Sleep(1000)
    Next
EndSwitch
  Until 0 ; повторяем поиск
EndFunc
;-------------------------------

Или грамотнее будет:

Код:
Func _aP1()
  Do
    ; находим все пиксели
    $aP1 = _PixelGetArray($X, $Y, $Width, $Height, 0xFFEE77, $hControl, True)
        ; кликаем по всем пикселям
    For $i = 1 To $aP1[0][0]
      ControlClick($hWnd, "", $hControl, "left", 1, $aP1[$i][0], $aP1[$i][1] + 60)
      Sleep(1000)
    Next
If Not $aP1[0][0] Then
    ; находим все пиксели
    $aP1 = _PixelGetArray($X, $Y, $Width, $Height, 0xFFFFFF, $hControl, True)
        ; кликаем по всем пикселям
    For $i = 1 To $aP1[0][0]
      ControlClick($hWnd, "", $hControl, "left", 1, $aP1[$i][0], $aP1[$i][1] + 60)
      Sleep(1000)
    Next
EndIf
  Until 0 ; повторяем поиск
EndFunc


Или я вообще всё не так понял
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Dessan
Или я вообще всё не так понял
И я тоже уже ничего не понимаю. То вам нужно было кликать по куче иконок, пока они не закончатся. Теперь вам нужно кликать по одной кнопке разного цвета. Но ведь это совсем не одно и то же.

Короче, мне это всё начинает надоедать.
 
Автор
D
Сообщения
137
Репутация
-2
Да, и мне, честно говоря

Мне нужно и то и другое. Сначала я хочу, что мне покликало на все золотые иконки, после клика она сами пропадают и появляются снова через 5 минут (этого я добился), затем на все серые иконки (этого я тоже добился), они так же пропадают после клика на них, на их месте появляются иконки тёмно-серого цвета. Вот с ними была вся проблема. После клика на них открывалось окно, с кнопкой тёмно-жёлтого цвета, а при наведении мышки на неё - цвет менялся на золотой. К тому же рядом ещё 5 таких же кнопок, и мне нужно было, чтоб скрипт кликал именно на первую, причём при нахождении либо тёмно-жёлтого, либо золотого пикселя. И это скрипт отказывался периодически делать - то пиксель не находил, то нажимал на рядом стоящие кнопки, несмотря на точно указанный квадрат поиска (так и не знаю почему).

Вообщем, мне вариант с введением условия
$aP1[0][0] будет равен нулю
подходит пока что. Спасибо, тема решена.
 
Верх