Что нового

Ошибка выхода из цикла while(ботоводство)

jollar

Новичок
Сообщения
11
Репутация
0
Есть функция, задача которой осуществлять действия в цикле while, пока не появится определённый пиксель. Но всё действие застреёт в while и не хочет завершать цикл. В чём я напутал?


Код:
Func fight()
Dim $combo[4]=[442,442,432,340] ; массив ударов
$cmnm = 0

While PixelGetColor(353,399)<>0x1F0802 ; Будем бить до того, как не появится окошко с победой и поражением
$cl2 = PixelGetColor(415,386) ; Это помогает ожидать, пауза, фильр
 
 While $cl2<>0xF4F4F4                     ; ожидаем очереди удара
$cl2 = PixelGetColor(415,386)   
WEnd
	

Switch $cmnm ; это не важно, идут удары
case 0
	MouseClick("left",$combo[0],$combo[2])
	$cmnm=$cmnm+1
case 1
	MouseClick("left",$combo[0],$combo[2])
	$cmnm=$cmnm+1
Case 2 
	MouseClick("left",$combo[1],$combo[3])
	$cmnm=$cmnm+1
Case 3
		MouseClick("left",$combo[1],$combo[3])
		$cmnm=0
	EndSwitch
WEnd
MouseClick("left",425,414)	; по-логике вот тут он должен нажимать на кнопку выхода из боя, но застреёт в While
EndFunc
 

NoMad73rus

Продвинутый
Сообщения
124
Репутация
80
Думаю тебе надо грамотно проставить
PixelCoordMode и MouseCoordMode
 

Garrett

Модератор
Локальный модератор
Сообщения
3 999
Репутация
964
Автор
J

jollar

Новичок
Сообщения
11
Репутация
0
NoMad73rus , хм...по координатам всё чётко. Перепроверил раз 200 наверно.


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

Garrett, хм...не понял вопроса.
 

Garrett

Модератор
Локальный модератор
Сообщения
3 999
Репутация
964

Yuri

AutoIT Гуру
Сообщения
737
Репутация
282
Может быть, просто ты забыл границу цикла обозначить (WEnd)

Код:
While PixelGetColor(353,399)<>0x1F0802 ; Будем бить до того, как не появится окошко с победой и поражением
$cl2 = PixelGetColor(415,386) ; Это помогает ожидать, пауза, фильр
 ;тут надо WEnd
 While $cl2<>0xF4F4F4                     ; ожидаем очереди удара
$cl2 = PixelGetColor(415,386)   
WEnd



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

Не. Это я - не внимательный:
2 While = 2Wend


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

Код:
MouseClick("left",425,414)

; по-логике вот тут он должен нажимать на кнопку выхода из боя, но застреёт в While
Вот и опиши логику. А тут ее нет. По логике должно вроде как-то так:
If Условие Then (или вместо Then - Case)
Действие (MouseClick("left",425,414)
EndIf
 
Автор
J

jollar

Новичок
Сообщения
11
Репутация
0
Хотя, ...
Вы по каким координатам ищите:
Screen
Window
Client
Эм..я затрудняюсь ответить. Для определения координат я использую AutoIt Window Info. Что она показывает, то и вставляю)


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

Вот и опиши логику. А тут ее нет. По логике должно вроде как-то так:
If Условие Then (или вместо Then - Case)
Действие (MouseClick("left",425,414)
EndIf
Эм...Тут это будет лишним нагромождением. Да и пробовал я так...он по какой-то причине из цикла не выходит. И я даже не могу понять где и по какой причине. Видно он не хочет снимать координаты в объявлении цикла:
While PixelGetColor(353,399)<>0x1F0802
Но дело и не в координатах, т.к. всё перепроверено...
 

Yuri

AutoIT Гуру
Сообщения
737
Репутация
282
PixelGetColor
Возвращаемое значение
Десятичное значение цвета позиции экрана.

While $cl2<>0xF4F4F4
Пока переменная $cl2 не бубет Будет равна значению 0xF4F4F4
Выполнять

В то время, как переменная $cl2 = PixelGetColor(415,386)
возвращает Десятичное значение.

Сравнивая десятичное с 16-ым (0xF4F4F4) мы всегда имеем False.
 

Garrett

Модератор
Локальный модератор
Сообщения
3 999
Репутация
964
jollar [?]
Для определения координат я использую AutoIt Window Info. Что она показывает, то и вставляю)
Вот вам и ответ, на мой вопрос!

Garrett [?]
Вы ищите pixel по координатам Screen
Установите в AutoIt Window Info поиск в Client области.
Options->Coord Mode->Client
Повторно определите координаты pixel`я и добавьте в скрипт следующие
Код:
;...
Opt('PixelCoordMode', 2)
$hWnd = WinGetHandle ('Заголовок вашего окна с игрой')
While Hex(PixelGetColor(x, y, $hWnd), 6) <> '1F0802'
;...
 
Автор
J

jollar

Новичок
Сообщения
11
Репутация
0
Эм...попробовал с Client...всё перестало работать вообще. ИМХО: пишу это я для себя, по этой причине можно использовать Screen, ведь ничего не меняется.

К тому же вставил Hex
Код:
While Hex(PixelGetColor(x, y) <> Hex( '1F0802')
Ничего не изменилось. РРР...
 

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
410
Может во While - Wend нужно поставить

Код:
If условие = чему-то Then
    ExitLoop
EndIf
Или я не так вопрос понял
 
Автор
J

jollar

Новичок
Сообщения
11
Репутация
0
Заметил нюанс:
1)Включаем скрипт, он удачно проходит бой
2)Доходит до финальной таблички с победой, на которую не хочет нажимать
3)Вырубаем скрипт и снова включаем
4)Он вполне завершает файт, нажимает на нужную кнопку с нужными координатами

То есть в итоге, есть где-то бесконечный цикл... Пытался ограничить вложенный While IF'ом: Если появляется табличка о победе, то цикл не выполняем - не помогло. Больше не знаю где дыра...Это 200% не координаты, не их представление...
 

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
410
Так тоже не будет работать?

Код:
Func fight()
	Dim $combo[4] = [442, 442, 432, 340] ; массив ударов
	$cmnm = 0

	While PixelGetColor(353, 399) <> 0x1F0802 ; Будем бить до того, как не появится окошко с победой и поражением
		$cl2 = PixelGetColor(415, 386) ; Это помогает ожидать, пауза, фильр

		While $cl2 <> 0xF4F4F4 ; ожидаем очереди удара
			If $cl2 = 0xF4F4F4 Then
				ExitLoop
			EndIf	
			$cl2 = PixelGetColor(415, 386)
		WEnd
		
		If PixelGetColor(353, 399) = 0x1F0802 Then
			ExitLoop
		EndIf	

		Switch $cmnm ; это не важно, идут удары
			Case 0
				MouseClick("left", $combo[0], $combo[2])
				$cmnm = $cmnm + 1
			Case 1
				MouseClick("left", $combo[0], $combo[2])
				$cmnm = $cmnm + 1
			Case 2
				MouseClick("left", $combo[1], $combo[3])
				$cmnm = $cmnm + 1
			Case 3
				MouseClick("left", $combo[1], $combo[3])
				$cmnm = 0
		EndSwitch
	WEnd
	MouseClick("left", 425, 414) ; по-логике вот тут он должен нажимать на кнопку выхода из боя, но застреёт в While
EndFunc   ;==>fight
 
Автор
J

jollar

Новичок
Сообщения
11
Репутация
0
Не..нифига.

Может это глюк самой AutoIT? У меня семёрка х64. Ибо на нетбуке она принципиально отказывалась запускать приложение командой "Run". Потому-что, тут ну не может быть ошибки...настолько простой код, что...первоклассник разберётся..
 

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
410
Сейчас проверим,попробуй так,тут когда появляется окно с победой то срабатывает
MouseClick по крайней мере должен

Код:
Func fight()
	Dim $combo[4] = [442, 442, 432, 340] ; массив ударов
	$cmnm = 0

	While PixelGetColor(353, 399) <> 0x1F0802 ; Будем бить до того, как не появится окошко с победой и поражением
		$cl2 = PixelGetColor(415, 386) ; Это помогает ожидать, пауза, фильр

        If PixelGetColor(353, 399) = 0x1F0802 Then
			MouseClick("left", 425, 414)
		EndIf	

		While $cl2 <> 0xF4F4F4 ; ожидаем очереди удара
			If $cl2 = 0xF4F4F4 Then
				ExitLoop
			EndIf	
			$cl2 = PixelGetColor(415, 386)
		WEnd
		
		Switch $cmnm ; это не важно, идут удары
			Case 0
				MouseClick("left", $combo[0], $combo[2])
				$cmnm = $cmnm + 1
			Case 1
				MouseClick("left", $combo[0], $combo[2])
				$cmnm = $cmnm + 1
			Case 2
				MouseClick("left", $combo[1], $combo[3])
				$cmnm = $cmnm + 1
			Case 3
				MouseClick("left", $combo[1], $combo[3])
				$cmnm = 0
		EndSwitch
	WEnd

EndFunc   ;==>fight
 
Автор
J

jollar

Новичок
Сообщения
11
Репутация
0
Нее..неа :laugh: :laugh: (У меня вот такое лицо\\офтоп)

В теле цикла он не хочет выполнять PixelGetColor. Он выполняет его один раз. Перед началом цикла...Я испробовал десяток различных вариантов...но эту команду он выполняет только один раз.
 

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
410
Значит вся проблема во втором While,когда запускается функция то срабатывает один раз PixelGetColor, дальше идёт второй цикл While на котором функция и тормозится до бесконечной обработки 2го цикла

Если опять не получится то я уже не знаю как сделать,либо не тот цвет возвращает для срабатывания

Код:
Func fight()
	Dim $combo[4] = [442, 442, 432, 340] ; массив ударов
	$cmnm = 0

	While PixelGetColor(353, 399) <> 0x1F0802 ; Будем бить до того, как не появится окошко с победой и поражением
		$cl2 = PixelGetColor(415, 386) ; Это помогает ожидать, пауза, фильр

        If PixelGetColor(353, 399) = 0x1F0802 Then
			MouseClick("left", 425, 414)
			ExitLoop
		EndIf	
	
		While $cl2 <> 0xF4F4F4 ; ожидаем очереди удара
			If $cl2 = 0xF4F4F4 Then
		        Switch $cmnm ; это не важно, идут удары
			        Case 0
				        MouseClick("left", $combo[0], $combo[2])
				        $cmnm = $cmnm + 1
			        Case 1
				        MouseClick("left", $combo[0], $combo[2])
				        $cmnm = $cmnm + 1
			        Case 2
				        MouseClick("left", $combo[1], $combo[3])
				        $cmnm = $cmnm + 1
			        Case 3
				        MouseClick("left", $combo[1], $combo[3])
				        $cmnm = 0
				EndSwitch				
			EndIf	
			$cl2 = PixelGetColor(415, 386)	
			ExitLoop
		WEnd
	WEnd

EndFunc
 
Автор
J

jollar

Новичок
Сообщения
11
Репутация
0
Ес. Убрал этот ****(плохой) цикл и начал выходить. Осталось придумать, каким образом его заменить...GOTO то нету(


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

Да и интересный вопрос, почему так происходит...
 

Garrett

Модератор
Локальный модератор
Сообщения
3 999
Репутация
964
jollar
Вот вам пример как работает PixelGetColor Думаю, он вам поможет понять логику.
Код:
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

Dim $Y = 0, $hWnd
Opt('PixelCoordMode', 2)
Opt('MouseCoordMode', 2)

$Form1 = GUICreate("PixelGetColor", 200, 54, 192, 114)
$Label1 = GUICtrlCreateLabel("", 33, 24, 1, 1)
GUICtrlSetBkColor(-1, 0xFF0000)
GUISetState(@SW_SHOW)

$hWnd = WinGetHandle("PixelGetColor")
If WinExists("PixelGetColor") Then
	AdlibRegister('_PixelGetColor')
EndIf

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit

	EndSwitch
WEnd

Func _PixelGetColor()

	For $X = 0 To 200
		If Hex(PixelGetColor($X, $Y, $hWnd), 6) = 'FF0000' Then 
			MsgBox(0, "Success!", "X: " & $X & @CRLF & "Y: " & $Y)
			AdlibUnRegister('_PixelGetColor')
			ExitLoop
		EndIf
		MouseMove($X, $Y, 1)
	Next
	$Y += 1
EndFunc


P.S. Мышку не трогайте до окончания!
 

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
410
В каком смысле GOTO - для чего он нужен?
 
Верх