Struggling with _PixelSearch - Snarg - 02-10-2015
I am attempting to re purpose some of the code in the bot, but I am running into issues with _PixelSearch. Specifically, I can not seem to get it to find the pixel I am looking for. I can not get it to find the pixel in the 'Train Troops' button. I am using an older version of BlueStacks and I don't have BS's resolution set to what you recommend however, that should not be the issue.
Let me apologize in advance to the wall of code but below is the code I am using. If the code worked, nothing should happen. But, I keep getting the 'Barracks is not available' messagebox instead.
If a super smart coder would like to take a look at this mess and let me know what I am doing wrong, I would appreciate it.
Code: #include <GDIPlus.au3>
#include <WinAPIProc.au3>
#include <ScreenCapture.au3>
#include <ColorConstants.au3>
#include <Misc.au3>
Opt("MouseClickDelay", 10)
Opt("MouseClickDownDelay", 10)
Global $hBitmap; Image for pixel functions
Global $hHBitmap; Handle Image for Pixel Functions
Global $BSpos[2] ; Inside BlueStacks positions relative to the screen
Global $ichkBackground = 0
$Title = "BlueStacks App Player for Windows (beta-1)" ; Window name
$Full = WinGetTitle ($Title) ; Get The Full Title..
$HWnD = WinGetHandle ($Full) ; Get The Handle
WinActivate ($HWnD)
WinMove ($HWnD, "", 0, 0)
Global $RunState = True
;Barrak 01 - 131, 309
;Barrak 02 - 296, 46
;Barrak 03 - 838, 50
;Barrak 04 - 994, 314
HotKeySet ("{F7}", "Train")
While 1
Sleep (100)
WEnd
Func Train()
While 1
If _Sleep(500) Then ExitLoop
Click(1, 1) ;Click Away
If _Sleep(500) Then ExitLoop
Click(131, 309) ;Click Barrack 01
If _Sleep(500) Then ExitLoop
Local $TrainPos = _PixelSearch(625, 457, 686, 520, Hex(0x885733, 6), 5) ;Finds Train Troops button
If IsArray($TrainPos) = False Then
;SetLog("Barrack " & $i + 1 & " is not available")
MsgBox ($MB_SYSTEMMODAL, "Barracks is not available", "")
If _Sleep(500) Then ExitLoop
Else
Click($TrainPos[0], $TrainPos[1]) ;Click Train Troops button
EndIf
WEnd
EndFunc ;==>Train
Func Click($x, $y, $times = 1, $speed = 0)
If $times <> 1 Then
For $i = 0 To ($times - 1)
ControlClick($HWnD, "", "", "left", "1", $x, $y)
If _Sleep($speed, False) Then ExitLoop
Next
Else
ControlClick($HWnD, "", "", "left", "1", $x, $y)
EndIf
EndFunc ;==>Click
Func _Sleep($iDelay, $iSleep = True)
Local $iBegin = TimerInit()
While TimerDiff($iBegin) < $iDelay
If $RunState = False Then Return True
If $iSleep = True Then Sleep(100)
WEnd
Return False
EndFunc ;==>_Sleep
Func _PixelSearch($iLeft, $iTop, $iRight, $iBottom, $iColor, $iColorVariation)
_CaptureRegion($iLeft, $iTop, $iRight, $iBottom)
For $x = $iRight - $iLeft To 0 Step -1
For $y = $iBottom - $iTop To 0 Step -1
Local $nColor1 = $iColor
Local $nColor2 = _PixelGetColor_GetPixel($x, $y)
If _ColorCheckVariation($nColor1, $nColor2, $iColorVariation) Then
Local $Pos[2] = [$iLeft + $x, $iTop + $y]
Return $Pos
EndIf
Next
Next
Return 0
EndFunc ;==>_PixelSearch
Func _CaptureRegion($iLeft = 0, $iTop = 0, $iRight = 860, $iBottom = 720, $ReturnBMP = False)
_GDIPlus_BitmapDispose($hBitmap)
_WinAPI_DeleteObject($hHBitmap)
If $ichkBackground = 1 Then
Local $iW = Number($iRight) - Number($iLeft), $iH = Number($iBottom) - Number($iTop)
Local $hDC_Capture = _WinAPI_GetWindowDC(ControlGetHandle("BlueStacks App Player", "", "[CLASS:BlueStacksApp; INSTANCE:1]"))
Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC_Capture)
$hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC_Capture, $iW, $iH)
Local $hObjectOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
DllCall("user32.dll", "int", "PrintWindow", "hwnd", $HWnD, "handle", $hMemDC, "int", 0)
_WinAPI_SelectObject($hMemDC, $hHBitmap)
_WinAPI_BitBlt($hMemDC, 0, 0, $iW, $iH, $hDC_Capture, $iLeft, $iTop, 0x00CC0020)
Global $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
_WinAPI_DeleteDC($hMemDC)
_WinAPI_SelectObject($hMemDC, $hObjectOld)
_WinAPI_ReleaseDC($HWnD, $hDC_Capture)
Else
getBSPos()
$hHBitmap = _ScreenCapture_Capture("", $iLeft + $BSpos[0], $iTop + $BSpos[1], $iRight + $BSpos[0], $iBottom + $BSpos[1])
Global $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
EndIf
If $ReturnBMP Then Return $hBitmap
EndFunc ;==>_CaptureRegion
Func getBSPos()
$aPos = ControlGetPos($Title, "", "[CLASS:BlueStacksApp; INSTANCE:1]")
$tPoint = DllStructCreate("int X;int Y")
DllStructSetData($tPoint, "X", $aPos[0])
DllStructSetData($tPoint, "Y", $aPos[1])
_WinAPI_ClientToScreen(WinGetHandle(WinGetTitle($Title)), $tPoint)
$BSpos[0] = DllStructGetData($tPoint, "X")
$BSpos[1] = DllStructGetData($tPoint, "Y")
EndFunc ;==>getBSPos
Func _PixelGetColor_GetPixel($iX, $iY)
Local $aPixelColor = _GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY)
Return Hex($aPixelColor, 6)
EndFunc ;==>_PixelGetColor_GetPixel
Func _ColorCheckVariation($nColor1, $nColor2, $sVari = 5)
Local $Red1, $Red2, $Blue1, $Blue2, $Green1, $Green2
$Red1 = Dec(StringMid(String($nColor1), 1, 2))
$Blue1 = Dec(StringMid(String($nColor1), 3, 2))
$Green1 = Dec(StringMid(String($nColor1), 5, 2))
$Red2 = Dec(StringMid(String($nColor2), 1, 2))
$Blue2 = Dec(StringMid(String($nColor2), 3, 2))
$Green2 = Dec(StringMid(String($nColor2), 5, 2))
If Abs($Blue1 - $Blue2) > $sVari Then Return False
If Abs($Green1 - $Green2) > $sVari Then Return False
If Abs($Red1 - $Red2) > $sVari Then Return False
Return True
EndFunc ;==>_ColorCheckVariation
RE: Struggling with _PixelSearch - Henk500 - 02-10-2015
Most likely you are not using the correct coords in your pixelsearch...
How did you get those coords?
RE: Struggling with _PixelSearch - Snarg - 02-10-2015
(02-10-2015, 04:47 PM)Henk500 Wrote: Most likely you are not using the correct coords in your pixelsearch...
How did you get those coords?
I am using Control Viewer.
RE: Struggling with _PixelSearch - Henk500 - 02-11-2015
(02-10-2015, 11:32 PM)Snarg Wrote: (02-10-2015, 04:47 PM)Henk500 Wrote: Most likely you are not using the correct coords in your pixelsearch...
How did you get those coords?
I am using Control Viewer.
I had some issues to... the x coordinate was not the coordinate i expected.
in my screenshot, $x=1 was the 3rd pixel.. I expected $x=1 to be the 2nd pixel ( and $x=0) the first pixel
RE: Struggling with _PixelSearch - Snarg - 02-11-2015
(02-11-2015, 12:10 AM)Henk500 Wrote: I had some issues to... the x coordinate was not the coordinate i expected.
in my screenshot, $x=1 was the 3rd pixel.. I expected $x=1 to be the 2nd pixel ( and $x=0) the first pixel
I can understand that. There is a bit of an offset with the coordinates. But I gave it a decent sized search area with the pixel I am looking for just about in the middle of the box.
Code: Local $TrainPos = _PixelSearch(625, 457, 686, 520, Hex(0x885733, 6), 5)
Here is my top left coordinates:
And here is my bottom right:
Do I have the coordinates wrong in the function call?
RE: Struggling with _PixelSearch - safar46 - 02-11-2015
in captureregion, change this value with your BS resolution
.....$iRight = 860, $iBottom = 720....
RE: Struggling with _PixelSearch - Snarg - 02-11-2015
(02-11-2015, 02:31 AM)safar46 Wrote: in captureregion, change this value with your BS resolution
.....$iRight = 860, $iBottom = 720....
It's always the blatantly obvious, isn't it? Thank you.
RE: Struggling with _PixelSearch - Snarg - 02-11-2015
(sigh) Still failing
Sorry for the wall of code, but here is the whole thing. All it should do is click a barracks and find the 'train troops' button.
Code: #include <GDIPlus.au3>
#include <WinAPIProc.au3>
#include <ScreenCapture.au3>
#include <ColorConstants.au3>
#include <Misc.au3>
Opt("MouseClickDelay", 10)
Opt("MouseClickDownDelay", 10)
Global $hBitmap; Image for pixel functions
Global $hHBitmap; Handle Image for Pixel Functions
Global $BSpos[2] ; Inside BlueStacks positions relative to the screen
Global $ichkBackground = 0
$Title = "BlueStacks App Player for Windows (beta-1)" ; Window name
$Full = WinGetTitle ($Title) ; Get The Full Title..
$HWnD = WinGetHandle ($Full) ; Get The Handle
WinActivate ($HWnD)
WinMove ($HWnD, "", 0, 0)
Global $RunState = True
;Barrak 01 - 131, 309
;Barrak 02 - 296, 46
;Barrak 03 - 838, 50
;Barrak 04 - 994, 314
HotKeySet ("{F7}", "Train")
While 1
Sleep (100)
WEnd
Func Train()
While 1
If _Sleep(500) Then ExitLoop
Click(1, 1) ;Click Away
If _Sleep(500) Then ExitLoop
Click(131, 309) ;Click Barrack 01
If _Sleep(500) Then ExitLoop
Local $TrainPos = _PixelSearch(625, 457, 686, 520, Hex(0x885733, 6), 5) ;Finds Train Troops button
If IsArray($TrainPos) = False Then
;SetLog("Barrack " & $i + 1 & " is not available")
MsgBox ($MB_SYSTEMMODAL, "Barracks is not available", "")
If _Sleep(500) Then ExitLoop
Else
MsgBox ($MB_SYSTEMMODAL, "Found it!!", "")
;Click($TrainPos[0], $TrainPos[1]) ;Click Train Troops button
EndIf
WEnd
EndFunc ;==>Train
Func Click($x, $y, $times = 1, $speed = 0)
If $times <> 1 Then
For $i = 0 To ($times - 1)
ControlClick($HWnD, "", "", "left", "1", $x, $y)
If _Sleep($speed, False) Then ExitLoop
Next
Else
ControlClick($HWnD, "", "", "left", "1", $x, $y)
EndIf
EndFunc ;==>Click
Func _Sleep($iDelay, $iSleep = True)
Local $iBegin = TimerInit()
While TimerDiff($iBegin) < $iDelay
If $RunState = False Then Return True
If $iSleep = True Then Sleep(100)
WEnd
Return False
EndFunc ;==>_Sleep
Func _PixelSearch($iLeft, $iTop, $iRight, $iBottom, $iColor, $iColorVariation)
_CaptureRegion($iLeft, $iTop, $iRight, $iBottom)
For $x = $iRight - $iLeft To 0 Step -1
For $y = $iBottom - $iTop To 0 Step -1
Local $nColor1 = $iColor
Local $nColor2 = _PixelGetColor_GetPixel($x, $y)
If _ColorCheckVariation($nColor1, $nColor2, $iColorVariation) Then
Local $Pos[2] = [$iLeft + $x, $iTop + $y]
Return $Pos
EndIf
Next
Next
Return 0
EndFunc ;==>_PixelSearch
Func _CaptureRegion($iLeft = 0, $iTop = 0, $iRight = 599, $iBottom = 1065, $ReturnBMP = False)
_GDIPlus_BitmapDispose($hBitmap)
_WinAPI_DeleteObject($hHBitmap)
If $ichkBackground = 1 Then
Local $iW = Number($iRight) - Number($iLeft), $iH = Number($iBottom) - Number($iTop)
Local $hDC_Capture = _WinAPI_GetWindowDC(ControlGetHandle("BlueStacks App Player", "", "[CLASS:BlueStacksApp; INSTANCE:1]"))
Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC_Capture)
$hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC_Capture, $iW, $iH)
Local $hObjectOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
DllCall("user32.dll", "int", "PrintWindow", "hwnd", $HWnD, "handle", $hMemDC, "int", 0)
_WinAPI_SelectObject($hMemDC, $hHBitmap)
_WinAPI_BitBlt($hMemDC, 0, 0, $iW, $iH, $hDC_Capture, $iLeft, $iTop, 0x00CC0020)
Global $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
_WinAPI_DeleteDC($hMemDC)
_WinAPI_SelectObject($hMemDC, $hObjectOld)
_WinAPI_ReleaseDC($HWnD, $hDC_Capture)
Else
getBSPos()
$hHBitmap = _ScreenCapture_Capture("", $iLeft + $BSpos[0], $iTop + $BSpos[1], $iRight + $BSpos[0], $iBottom + $BSpos[1])
Global $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
EndIf
If $ReturnBMP Then Return $hBitmap
EndFunc ;==>_CaptureRegion
Func getBSPos()
$aPos = ControlGetPos($Title, "", "[CLASS:BlueStacksApp; INSTANCE:1]")
$tPoint = DllStructCreate("int X;int Y")
DllStructSetData($tPoint, "X", $aPos[0])
DllStructSetData($tPoint, "Y", $aPos[1])
_WinAPI_ClientToScreen(WinGetHandle(WinGetTitle($Title)), $tPoint)
$BSpos[0] = DllStructGetData($tPoint, "X")
$BSpos[1] = DllStructGetData($tPoint, "Y")
EndFunc ;==>getBSPos
Func _PixelGetColor_GetPixel($iX, $iY)
Local $aPixelColor = _GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY)
Return Hex($aPixelColor, 6)
EndFunc ;==>_PixelGetColor_GetPixel
Func _ColorCheckVariation($nColor1, $nColor2, $sVari = 5)
Local $Red1, $Red2, $Blue1, $Blue2, $Green1, $Green2
$Red1 = Dec(StringMid(String($nColor1), 1, 2))
$Blue1 = Dec(StringMid(String($nColor1), 3, 2))
$Green1 = Dec(StringMid(String($nColor1), 5, 2))
$Red2 = Dec(StringMid(String($nColor2), 1, 2))
$Blue2 = Dec(StringMid(String($nColor2), 3, 2))
$Green2 = Dec(StringMid(String($nColor2), 5, 2))
If Abs($Blue1 - $Blue2) > $sVari Then Return False
If Abs($Green1 - $Green2) > $sVari Then Return False
If Abs($Red1 - $Red2) > $sVari Then Return False
Return True
EndFunc ;==>_ColorCheckVariation
|