Что нового

Ошибки Работа с неактивным окном PixelSearch (не получается)

sasha21l

Новичок
Сообщения
1
Репутация
0
Добрый день очень нужна Ваша помощь...
Мой код

Код:
#include <WinAPIGdi.au3>
#include <Color.au3>

$hWnd = WinGetHandle("[CLASS:ElementClient Window]") ;Указываем окно
WinActivate($hWnd) ;Активируем окно
Opt("PixelCoordMode",0) ; Меняем начало координат
$i = 0
While $i = 0 ;Бесконечный цикл
Sleep(300)
HeroHP() ;Функция проверки ЖС персонажа
Lut() ;Функция поднятия лута
DeadMob() ;Выделение нового моба
Ataka() ;Атака мобов
HeroMANA() ;Функция проверки Манны персонажа

WEnd ; Конец бесконечного цикла

Func HeroHP()  ;Функция проверки ЖС персонажа
   $coord = PixelSearch(230, 40, 290, 80, 0xC9050A, 0, 1, $hWnd) ;Проверка есть ли в указанных координатах жизни
If @error = 1 then
ControlSend($hWnd, "", "", "{F6}") ; Если нету то принимаем бутылочку жс
endif

EndFunc

Func HeroMANA()  ;Функция проверки Манны персонажа
   $coord = PixelSearch(230, 40, 290, 80, 0x055FC9, 0, 1, $hWnd) ;Проверка есть ли в указанных координатах манна
If @error = 1 then
ControlSend($hWnd, "", "", "{F8}") ; Если нету то принимаем бутылочку манны
endif

EndFunc

Func DeadMob() ;Выделение нового моба
   $coord = PixelSearch(320, 15, 500, 60, 0xC9050A, 0, 1, $hWnd) ;Проверка есть ли в указанных координатах хеллбар выделенного моба
If @error = 1 then
ControlSend($hWnd, "", "", "{TAB}") ;если нету то берем в таргет ближайшего моба
endif
EndFunc

Func Ataka() ;Атака мобов
   ControlSend($hWnd, "", "", "{F1}")
   Sleep(Random(800, 1500))
EndFunc

Func Lut()  ;Функция поднятия лута
   $coord = PixelSearch(320, 15, 500, 60, 0xC9050A, 0, 1, $hWnd) ;Проверка есть ли в указанных координатах хеллбар выделенного моба
If @error = 1 then ;Если нету то скорее всего моб мертв и надо собрать с него лут.
For $i = 1 To 5
   ControlSend($hWnd, "", "", "{F4}")
   Sleep(Random(800, 1200))
Next
ControlSend($hWnd, "", "", "{F7}")
ControlSend($hWnd, "", "", "{F3}")
endif

EndFunc


К сожалению мой код работает только в активном окне и я начал искать выход из ситуации.
Прочитал эту тему http://autoit-script.ru/threads/avtomatizacija-rabota-so-svjornutoj-igroj-koncepcija-ne-meshajuschego-bota.4462/


Там предложен такой вариант

Код:
Global $hDDC, $hCDC, $hBMP
AdlibRegister("_BitmapWin", 500)
Func _detekt ($iX, $iY)
        $sColor = _WinAPI_GetPixel($hCDC, $iX, $iY)
        Return $sColor
EndFunc
Func _BitmapWin()
    _WinAPI_DeleteDC($hCDC)
    _WinAPI_DeleteObject($hBMP) ; очищаем битовый массив
    $iWidth = _WinAPI_GetWindowWidth($hWnd)
    $iHeight = _WinAPI_GetWindowHeight($hWnd)
    $hDDC = _WinAPI_GetDC($hWnd)
    $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iWidth, $iHeight)
    _WinAPI_SelectObject($hCDC, $hBMP)
    DllCall("User32.dll", "int", "PrintWindow", "hwnd", $hWnd, "hwnd", $hCDC, "int", 0)
    $sColor = _WinAPI_GetPixel($hCDC, $iX, $iY)
    _WinAPI_ReleaseDC($hWnd, $hDDC)
EndFunc
Func _SearchPix($x1, $y1, $x2, $y2, $coll, $shvar=0, $step=1)
    $ARGB = _WinAPI_IntToDWord(BitOR($coll, 0xFF000000))
    $Size = WinGetClientSize($hWnd)
    $L1 = $Size[0]*($y1-1)+$x1
    $L2 = $Size[0]*($y2-1)+$x2
    $L = $Size[0] * $Size[1]
    $tBits = DllStructCreate('dword[' & $L & ']')
    _WinAPI_GetBitmapBits($hBMP, 4 * $L, DllStructGetPtr($tBits))
    $Offset = -1
    For $i = $L1 To $L2 Step $step
        If DllStructGetData($tBits, 1, $i) = $ARGB Then
            $Offset = $i
            ExitLoop
        EndIf
    Next
    If $Offset = -1 Then
        Return SetError(1)
    Else
        $x = Mod($Offset, $Size[0]) - 1
        $y = Ceiling($Offset / $Size[0]) - 1
        Local $coor[2] = [$x, $y]
        Return $coor
    EndIf
EndFunc


Я попытался использовать этот пример чтобы улучшить мой код,
получилось вот это

Код:
#include <WinAPIGdi.au3>
#include <Color.au3>
#include <WinAPIEx.au3>

Global $hDDC, $hCDC, $hBMP

$hWnd = WinGetHandle("[CLASS:ElementClient Window]") ;Указываем окно
WinActivate($hWnd) ;Активируем окно
Opt("PixelCoordMode",0) ; Меняем начало координат
$i = 0
While $i = 0 ;Бесконечный цикл
Sleep(300)
HeroHP() ;Функция проверки ЖС персонажа
Lut() ;Функция поднятия лута
DeadMob() ;Выделение нового моба
Ataka() ;Атака мобов
HeroMANA() ;Функция проверки Манны персонажа

WEnd ; Конец бесконечного цикла

Func HeroHP()  ;Функция проверки ЖС персонажа
   $coord = Func _SearchPix(230, 40, 290, 80, 0xC9050A, 0, 1, $hWnd) ;Проверка есть ли в указанных координатах жизни (НОВАЯ)
If @error = 1 then
ControlSend($hWnd, "", "", "{F6}") ; Если нету то принимаем бутылочку жс
endif

EndFunc

Func HeroMANA()  ;Функция проверки Манны персонажа
   $coord = Func _SearchPix(230, 40, 290, 80, 0x055FC9, 0, 1, $hWnd) ;Проверка есть ли в указанных координатах манна (НОВАЯ)
If @error = 1 then
ControlSend($hWnd, "", "", "{F8}") ; Если нету то принимаем бутылочку манны
endif

EndFunc

Func DeadMob() ;Выделение нового моба
   $coord = Func _SearchPix(320, 15, 500, 60, 0xC9050A, 0, 1, $hWnd) ;Проверка есть ли в указанных координатах хеллбар выделенного моба (НОВАЯ)
If @error = 1 then
ControlSend($hWnd, "", "", "{TAB}") ;если нету то берем в таргет ближайшего моба
endif
EndFunc

Func Ataka() ;Атака мобов
   ControlSend($hWnd, "", "", "{F1}")
   Sleep(Random(800, 1500))
EndFunc

Func Lut()  ;Функция поднятия лута
   $coord = Func _SearchPix(320, 15, 500, 60, 0xC9050A, 0, 1, $hWnd) ;Проверка есть ли в указанных координатах хеллбар выделенного моба (НОВАЯ)
If @error = 1 then ;Если нету то скорее всего моб мертв и надо собрать с него лут.
For $i = 1 To 5
   ControlSend($hWnd, "", "", "{F4}")
   Sleep(Random(800, 1200))
Next
ControlSend($hWnd, "", "", "{F7}")
ControlSend($hWnd, "", "", "{F3}")
endif

EndFunc


Func _BitmapWin() ; Добавлена новая функция
    _WinAPI_DeleteDC($hCDC)
    _WinAPI_DeleteObject($hBMP) ; очищаем битовый массив
    $iWidth = _WinAPI_GetWindowWidth($hWnd)
    $iHeight = _WinAPI_GetWindowHeight($hWnd)
    $hDDC = _WinAPI_GetDC($hWnd)
    $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iWidth, $iHeight)
    _WinAPI_SelectObject($hCDC, $hBMP)
    DllCall("User32.dll", "int", "PrintWindow", "hwnd", $hWnd, "hwnd", $hCDC, "int", 0)
    $sColor = _WinAPI_GetPixel($hCDC, $iX, $iY)
    _WinAPI_ReleaseDC($hWnd, $hDDC)
EndFunc

Func _SearchPix($x1, $y1, $x2, $y2, $coll, $shvar=0, $step=1) ; Добавлена новая функция
    AdlibRegister("_BitmapWin", 500)
    $ARGB = _WinAPI_IntToDWord(BitOR($coll, 0xFF000000))
    $Size = WinGetClientSize($hWnd)
    $L1 = $Size[0]*($y1-1)+$x1
    $L2 = $Size[0]*($y2-1)+$x2
    $L = $Size[0] * $Size[1]
    $tBits = DllStructCreate('dword[' & $L & ']')
    _WinAPI_GetBitmapBits($hBMP, 4 * $L, DllStructGetPtr($tBits))
    $Offset = -1
    For $i = $L1 To $L2 Step $step
        If DllStructGetData($tBits, 1, $i) = $ARGB Then
            $Offset = $i
            ExitLoop
        EndIf
    Next
    If $Offset = -1 Then
        Return SetError(1)
    Else
        $x = Mod($Offset, $Size[0]) - 1
        $y = Ceiling($Offset / $Size[0]) - 1
        Local $coor[2] = [$x, $y]
        Return $coor
    EndIf
EndFunc


Но у меня ничего не работает(((
Мужики помогите пожалуйста!
Сообщение автоматически объединено:

 
Последнее редактирование:

InnI

AutoIT Гуру
Сообщения
4 331
Репутация
1 168
Код:
$coord = Func _SearchPix(230, 40, 290, 80, 0xC9050A, 0, 1, $hWnd)

При вызове функции не нужно указывать Func
В описании функции семь параметров. Следовательно, $hWnd здесь лишний. К тому же он глобальный.
Вот так правильно
Код:
$coord = _SearchPix(230, 40, 290, 80, 0xC9050A, 0, 1)


В вашем случае эта строка не нужна
Код:
$sColor = _WinAPI_GetPixel($hCDC, $iX, $iY)


AdlibRegister лучше вынести в начало скрипта. А ещё лучше вызывать _BitmapWin не через AdlibRegister, а напрямую в цикле после Sleep(300). Иначе могут возникнуть накладки, когда часть функций выполнится на старом скриншоте, а часть на новом.

Также, добавьте для отладки сохранение полученного снимка в файл
Код:
...
    DllCall("User32.dll", "int", "PrintWindow", "hwnd", $hWnd, "hwnd", $hCDC, "int", 0)
    _WinAPI_SaveHBITMAPToFile("test.bmp", $hBMP) ; <=== отладка (запись снимка в файл)
    ; $sColor = _WinAPI_GetPixel($hCDC, $iX, $iY) ; лишняя строка
    _WinAPI_ReleaseDC($hWnd, $hDDC)
...
 
Верх