Skocz do zawartości
  • 0

Klikanie w punkty na mapie


Adrstalik
 Udostępnij

Pytanie

Cześć,

Potrzebuje Waszej pomocy. Napisałem kod, który przeszukuje okno mapy w poszukiwaniu pixela. Niestety nie bardzo mam pomysł, jak zrobić tak, aby klikając w jeden punkt na mapie szedł dalej, a nie wyszukiwał pixeli wcześniejszych. 

Tu kod:

While 1
    If _IsPressed('1B') Then
        Exit
    EndIf
    For $i = 1 To 2
        If $i = 1 Then
            For $w = $WPos[0] + 15 To $WPos[2] Step 10
                $dot = PixelSearch($w, $h, $w + 10, $WPos[3] - 30, 0xffffff, 0, 1)
                If Not @error Then
                    If $xPrev <> 0 Or $yPrev <> 0 Then
                    Pixel_Distance($xPrev, $yPrev, $dot[0], $dot[1])
                    EndIf
                    MouseMove($dot[0], $dot[1], 5)
                    $xPrev = $dot[0]
                    $yPrev = $dot[1]
                EndIf
            Next
        Else
            For $w = $WPos[2] To $WPos[0] + 15 Step -10
                $dot = PixelSearch($w, $h, $w - 10, $WPos[3] - 30, 0xff4646, 0, 1)
                If Not @error Then
                    If $xPrev <> 0 Or $yPrev <> 0 Then
                    Pixel_Distance($xPrev, $yPrev, $dot[0], $dot[1])
                    EndIf
                    MouseMove($dot[0], $dot[1], 5)
                    $xPrev = $dot[0]
                    $yPrev = $dot[1]
                EndIf
            Next
        EndIf
    Next
WEnd

Tu przykład jak skrypt działa: 

przykład.gif

Jak widzimy na gifie: Skrypt sprawdza jak daleko jest czerwony X. W pewnym momencie przestaje widzieć dalszy pixel (co jest w porządku), ale nawet gdy w miejscu zielonych fajek są czerwone krzyże, niestety skrypt nie potrafi przejść dalej. 

Wyglądało by to tak: 

przykład2.gif

Ma ktoś jakieś pomysły? 

 

Dzięki

 

Edytowane przez Adrstalik
literówka

Kocham mpcforum.pl!!!

18706.png

Odnośnik do komentarza
Udostępnij na innych stronach

22 odpowiedzi na to pytanie

Rekomendowane odpowiedzi

  • 0

Napisałem ale nadal mam ten problem..

Tu nowy kod:

Global $WPos1 = [1206,266,1260,321]
Global $WPos2 = [1260,266,1313,321]
Global $WPos3 = [1206,321,1260,376]
Global $WPos4 = [1260,321,1313,376]

Global $h1 = $WPos1[1]
Global $h2 = $WPos2[1]
Global $h3 = $WPos3[1]
Global $h4 = $WPos4[1]

Global $dot1 = 0
Global $dot2 = 0
Global $dot3 = 0
Global $dot4 = 0

Global $xPrev = 0, $yPrev = 0, $PDist

While 1
    If _IsPressed('1B') Then
        Exit
    EndIf
For $i = 1 to 8
	If $i = 1 Then
		For $w = $WPos1[0] + 2 to $WPos1[2] Step 10
		$dot1 = PixelSearch($w, $h1, $w + 1, $WPos1[3] - 3, 0xff4646, 0, 1)
		 If Not @error Then
                    If $xPrev <> 0 Or $yPrev <> 0 Then
                    Pixel_Distance($xPrev, $yPrev, $dot1[0], $dot1[1])
                    EndIf
                    MouseMove($dot1[0], $dot1[1], 5)
                    $xPrev = $dot1[0]
                    $yPrev = $dot1[1]
                EndIf
	Next
Else
For $w = $WPos1[2] To $WPos1[0] + 2 Step -10
                $dot1 = PixelSearch($w, $h1, $w - 1, $WPos1[3] - 3, 0xff4646, 0, 1)
                If Not @error Then
                    If $xPrev <> 0 Or $yPrev <> 0 Then
                    Pixel_Distance($xPrev, $yPrev, $dot1[0], $dot1[1])
                    EndIf
                    MouseMove($dot1[0], $dot1[1], 5)
                    $xPrev = $dot1[0]
                    $yPrev = $dot1[1]
                EndIf
			Next
		EndIf
For $w = $WPos2[0] + 2 to $WPos2[2] Step 10
		$dot2 = PixelSearch($w, $h2, $w + 1, $WPos2[3] - 3, 0xff4646, 0, 1)
		 If Not @error Then
                    If $xPrev <> 0 Or $yPrev <> 0 Then
                    Pixel_Distance($xPrev, $yPrev, $dot2[0], $dot2[1])
                    EndIf
                    MouseMove($dot2[0], $dot2[1], 5)
                    $xPrev = $dot2[0]
                    $yPrev = $dot2[1]
                EndIf
Next
For $w = $WPos2[2] To $WPos2[0] + 2 Step -10
                $dot2 = PixelSearch($w, $h2, $w - 1, $WPos2[3] - 3, 0xff4646, 0, 1)
                If Not @error Then
                    If $xPrev <> 0 Or $yPrev <> 0 Then
                    Pixel_Distance($xPrev, $yPrev, $dot2[0], $dot2[1])
                    EndIf
                    MouseMove($dot2[0], $dot2[1], 5)
                    $xPrev = $dot2[0]
                    $yPrev = $dot2[1]
                EndIf
            Next
For $w = $WPos3[0] + 2 to $WPos3[2] Step 10
		$dot3 = PixelSearch($w, $h3, $w + 1, $WPos3[3] - 3, 0xff4646, 0, 1)
		 If Not @error Then
                    If $xPrev <> 0 Or $yPrev <> 0 Then
                    Pixel_Distance($xPrev, $yPrev, $dot3[0], $dot3[1])
                    EndIf
                    MouseMove($dot3[0], $dot3[1], 5)
                    $xPrev = $dot3[0]
                    $yPrev = $dot3[1]
                EndIf
Next
For $w = $WPos3[2] To $WPos3[0] + 2 Step -10
                $dot3 = PixelSearch($w, $h3, $w - 1, $WPos3[3] - 3, 0xff4646, 0, 1)
                If Not @error Then
                    If $xPrev <> 0 Or $yPrev <> 0 Then
                    Pixel_Distance($xPrev, $yPrev, $dot3[0], $dot3[1])
                    EndIf
                    MouseMove($dot3[0], $dot3[1], 5)
                    $xPrev = $dot3[0]
                    $yPrev = $dot3[1]
                EndIf
Next
For $w = $WPos4[0] + 2 to $WPos4[2] Step 10
		$dot4 = PixelSearch($w, $h4, $w + 1, $WPos4[3] - 3, 0xff4646, 0, 1)
		 If Not @error Then
                    If $xPrev <> 0 Or $yPrev <> 0 Then
                    Pixel_Distance($xPrev, $yPrev, $dot4[0], $dot4[1])
                    EndIf
                    MouseMove($dot4[0], $dot4[1], 5)
                    $xPrev = $dot4[0]
                    $yPrev = $dot4[1]
                EndIf
Next
For $w = $WPos4[2] To $WPos4[0] + 2 Step -10
                $dot4 = PixelSearch($w, $h4, $w - 1, $WPos4[3] - 3, 0xff4646, 0, 1)
                If Not @error Then
                    If $xPrev <> 0 Or $yPrev <> 0 Then
                    Pixel_Distance($xPrev, $yPrev, $dot4[0], $dot4[1])
                    EndIf
                    MouseMove($dot4[0], $dot4[1], 5)
                    $xPrev = $dot4[0]
                    $yPrev = $dot4[1]
                EndIf
            Next
    Next
WEnd

Ktoś coś? 

Kocham mpcforum.pl!!!

18706.png

Odnośnik do komentarza
Udostępnij na innych stronach

  • 0

Tyllo w dalszym ciagu nie jest to kod ktory moge skopiowac i odpalic u siebie.

Co robi funkcja Pixel_Distance?

Albo po co jest 

Cytat

For $i = 1 to 8

albo

Cytat

If $i = 1 Then

MouseMove tez wyglada na zbedny

 

Moja propozycja:

#include "FastFind.au3"
#include <MsgBoxConstants.au3>
#include <Array.au3>

HotKeySet("{HOME}", "_START")
HotKeySet("{END}", "_EXIT")

Global $MARK_COLOR = '00FF4646'						; Kolor Znacznika
Global $MINIMAP_AREA = [[1743, 31], [1911, 175]]	; Obszar minimapy
Global $CENTER = [1825, 100]						; Srodek

Func _START()
	Local $Marks = findMarks()
	Local $invalid_quarters = Null 	; Numer wykluczonej cwiartki, na poczatku nie chcemy nic wykluczac
	While 1
		If IsInactive() Then
			$Marks = findMarks()
			$invalid_quarters = makeMove($Marks, $invalid_quarters)
		EndIf
		Sleep(100)
	WEnd
EndFunc


; Zwraca posortowana liste znacznikow
Func findMarks()
	Local $aMarks = [[0, 0, 0, 0]]
	FFSnapShot()

	For $x = $MINIMAP_AREA[0][0] To $MINIMAP_AREA[1][0]
		For $y = $MINIMAP_AREA[0][1] To $MINIMAP_AREA[1][1]
			If Hex(FFGetPixel($x,$y)) == $MARK_COLOR Then
				_ArrayAdd($aMarks, $x & "|" & $y & "|" & getQuarter($x, $y) & "|" & getDistance($x, $y))
			EndIf
		Next
	Next

	If UBound($aMarks) <= 1 Then
		MsgBox($MB_ICONERROR, '', 'Brak punktów na mapie')
		Exit
	EndIf
	_ArraySort($aMarks, 0, 0, 0, 3) ; sortowanie po dystansie

	; COL 0 - X
	; COL 1 - Y
	; COL 2 - Cwiartka
	; COL 3 - Odleglosc do punktu
	;_ArrayDisplay($aMarks)
	Return $aMarks
EndFunc


; Wyznacza cwiartke
; Bedzie problem jezeli x == 0 lub y == 0
Func getQuarter($x, $y)
	$x = $x - $CENTER[0]
	$y = $y - $CENTER[1]

	If $x > 0 And $y < 0 Then
		Return 1
	ElseIf $x < 0 And $y < 0 Then
		Return 2
	ElseIf $x < 0 And $y > 0 Then
		Return 3
	ElseIf $x > 0 And $y > 0 Then
		Return 4
	EndIf
EndFunc

; Dystans
Func getDistance($x, $y)
	$x = Abs($x - $CENTER[0])
	$y = Abs($y - $CENTER[1])
	Return $x + $y
EndFunc

; Wykonuje ruch i zwraca cwiartke ktora wykluczymy przy nastepnym ruchu
Func makeMove($aMarks, $invalid_quarters)
	Local $gotoX = 0
	Local $gotoY = 0
	Local $quarter = 0

	For $i=1 To UBound($aMarks)-1
		$quarter = $aMarks[$i][2]
		If isInInvalidQuarter($quarter, $invalid_quarters) Then
			ContinueLoop
		EndIf
		$gotoX = $aMarks[$i][0]
		$gotoY = $aMarks[$i][1]
		ExitLoop
	Next

	If $gotoX > 0 And $gotoY > 0 Then
		MouseMove($gotoX, $gotoY, 0)
		Sleep(250)
		MouseClick("left")
		Return getInvalidQuarter($quarter)
	Else
		MsgBox($MB_ICONERROR, '', 'Nie udało się wykonać ruchu, wszystkie punkty są w wykluczonej cwiartce')
		Exit
	EndIf
EndFunc

; Zwraca cwiartke ktora bedziemy ignorowac
Func getInvalidQuarter($quarter)
	Switch ($quarter)
		Case 1
			Return 3
		Case 2
			Return 4
		Case 3
			Return 1
		Case 4
			Return 2
		Case Else
			MsgBox($MB_ICONERROR, '', "What's wrong dude?")
	EndSwitch
EndFunc

; Zwraca True jezeli znacznik jest w wykluczonej cwiartce
Func isInInvalidQuarter($quarter, $invalid_quarters)
	If IsArray($invalid_quarters) Then
		For $q In $invalid_quarters
			If $quarter == $q Then Return True
		Next
	Else
		Return $quarter == $invalid_quarters
	EndIf

	Return False
EndFunc

; Zwraca True jezeli postac sie nie porusza
Func IsInactive()
	Local $cheksum1 = PixelChecksum($MINIMAP_AREA[0][0], $MINIMAP_AREA[0][1], $MINIMAP_AREA[1][0], $MINIMAP_AREA[1][1])
	Sleep(1500)
	Local $cheksum2 = PixelChecksum($MINIMAP_AREA[0][0], $MINIMAP_AREA[0][1], $MINIMAP_AREA[1][0], $MINIMAP_AREA[1][1])
	Return $cheksum1 == $cheksum2
EndFunc

Func _EXIT()
	Exit
EndFunc

While 1
	Sleep(100)
WEnd

 

Zachowane formatiowanie kodu -> https://pastebin.com/q1BDxDrr

Korzystam z fastfinda bo jest duzo wydajniejszy https://www.autoitscript.com/forum/topic/126430-advanced-pixel-search-library/

 

Podzielilem tez minimape troche inaczej:

RzDL7IN.png

 

Generalnie trzeba uwazac przy ustawianiu znacznikow, ale z tym raczej wiele nie da sie zrobic.

 

 

Odnośnik do komentarza
Udostępnij na innych stronach

  • 0

Wystarczy dopisac if'a ktory bedzie ignorowal punkty ktore sa zbyt blisko, nie wiem w czym problem...

np.

Func makeMove($aMarks, $invalid_quarters)
	Local $gotoX = 0
	Local $gotoY = 0
	Local $quarter = 0
	Local $dist = 0

	For $i=1 To UBound($aMarks)-1
		$quarter = $aMarks[$i][2]
		If isInInvalidQuarter($quarter, $invalid_quarters) Then
			ContinueLoop
		EndIf
		
		$dist = $aMarks[$i][3]
		If $dist <= 3 Then
			ContinueLoop
		EndIf
		$gotoX = $aMarks[$i][0]
		$gotoY = $aMarks[$i][1]
		ExitLoop
	Next

	If $gotoX > 0 And $gotoY > 0 Then
		MouseMove($gotoX, $gotoY, 0)
		Sleep(250)
		MouseClick("left")
		Return getInvalidQuarter($quarter)
	Else
		MsgBox($MB_ICONERROR, '', 'Nie udało się wykonać ruchu, wszystkie punkty są w wykluczonej cwiartce')
		Exit
	EndIf
EndFunc

 

 

 

Odnośnik do komentarza
Udostępnij na innych stronach

  • 0

https://zapodaj.net/d7f06c12a60a9.jpg.html

 

#include "FastFind.au3"
#include <MsgBoxConstants.au3>
#include <Array.au3>

HotKeySet("{HOME}", "_START")
HotKeySet("{END}", "_EXIT")

Global $MARK_COLOR = 0xFF4646                   ; Kolor Znacznika
Global $MINIMAP_AREA = [[1199, 27], [1304, 135]]    ; Obszar minimapy
Global $CENTER = [1251, 81]                        ; Srodek

Func _START()
	Local $Marks = findMarks()
	Local $invalid_quarters = Null 	; Numer wykluczonej cwiartki, na poczatku nie chcemy nic wykluczac
	While 1
		If IsInactive() Then
			$Marks = findMarks()
			$invalid_quarters = makeMove($Marks, $invalid_quarters)
		EndIf
		Sleep(100)
	WEnd
EndFunc


; Zwraca posortowana liste znacznikow
Func findMarks()
	Local $aMarks = [[0, 0, 0, 0]]
	FFSnapShot()

	For $x = $MINIMAP_AREA[0][0] To $MINIMAP_AREA[1][0]
		For $y = $MINIMAP_AREA[0][1] To $MINIMAP_AREA[1][1]
			If Hex(FFGetPixel($x,$y)) == $MARK_COLOR Then
				_ArrayAdd($aMarks, $x & "|" & $y & "|" & getQuarter($x, $y) & "|" & getDistance($x, $y))
			EndIf
		Next
	Next

	If UBound($aMarks) <= 1 Then
		MsgBox($MB_ICONERROR, '', 'Brak punktów na mapie')
		Exit
	EndIf
	_ArraySort($aMarks, 0, 0, 0, 3) ; sortowanie po dystansie

	; COL 0 - X
	; COL 1 - Y
	; COL 2 - Cwiartka
	; COL 3 - Odleglosc do punktu
	;_ArrayDisplay($aMarks)
	Return $aMarks
EndFunc


; Wyznacza cwiartke
; Bedzie problem jezeli x == 0 lub y == 0
Func getQuarter($x, $y)
	$x = $x - $CENTER[0]
	$y = $y - $CENTER[1]

	If $x > 0 And $y < 0 Then
		Return 1
	ElseIf $x < 0 And $y < 0 Then
		Return 2
	ElseIf $x < 0 And $y > 0 Then
		Return 3
	ElseIf $x > 0 And $y > 0 Then
		Return 4
	EndIf
EndFunc

; Dystans
Func getDistance($x, $y)
	$x = Abs($x - $CENTER[0])
	$y = Abs($y - $CENTER[1])
	Return $x + $y
EndFunc

; Wykonuje ruch i zwraca cwiartke ktora wykluczymy przy nastepnym ruchu
Func makeMove($aMarks, $invalid_quarters)
	Local $gotoX = 0
	Local $gotoY = 0
	Local $quarter = 0

	For $i=1 To UBound($aMarks)-1
		$quarter = $aMarks[$i][2]
		If isInInvalidQuarter($quarter, $invalid_quarters) Then
			ContinueLoop
		EndIf
		$gotoX = $aMarks[$i][0]
		$gotoY = $aMarks[$i][1]
		ExitLoop
	Next

	If $gotoX > 0 And $gotoY > 0 Then
		MouseMove($gotoX, $gotoY, 0)
		Sleep(250)
		MouseClick("left")
		Return getInvalidQuarter($quarter)
	Else
		MsgBox($MB_ICONERROR, '', 'Nie udało się wykonać ruchu, wszystkie punkty są w wykluczonej cwiartce')
		Exit
	EndIf
EndFunc

; Zwraca cwiartke ktora bedziemy ignorowac
Func getInvalidQuarter($quarter)
	Switch ($quarter)
		Case 1
			Return 3
		Case 2
			Return 4
		Case 3
			Return 1
		Case 4
			Return 2
		Case Else
			MsgBox($MB_ICONERROR, '', "What's wrong dude?")
	EndSwitch
EndFunc

; Zwraca True jezeli znacznik jest w wykluczonej cwiartce
Func isInInvalidQuarter($quarter, $invalid_quarters)
	If IsArray($invalid_quarters) Then
		For $q In $invalid_quarters
			If $quarter == $q Then Return True
		Next
	Else
		Return $quarter == $invalid_quarters
	EndIf

	Return False
EndFunc

; Zwraca True jezeli postac sie nie porusza
Func IsInactive()
	Local $cheksum1 = PixelChecksum($MINIMAP_AREA[0][0], $MINIMAP_AREA[0][1], $MINIMAP_AREA[1][0], $MINIMAP_AREA[1][1])
	Sleep(1500)
	Local $cheksum2 = PixelChecksum($MINIMAP_AREA[0][0], $MINIMAP_AREA[0][1], $MINIMAP_AREA[1][0], $MINIMAP_AREA[1][1])
	Return $cheksum1 == $cheksum2
EndFunc

Func _EXIT()
	Exit
EndFunc

While 1
	Sleep(100)
WEnd

 

Edytowane przez lolasek16
Odnośnik do komentarza
Udostępnij na innych stronach

  • 0

A dało by się prosciej zrobić żeby szedł do punktu A poczekał 10 sekund (tylko żeby czekanie nie pauzowało całego skryptu) potem do punktu B itp. Wszystkie znaczniki były by innego koloru. Nie umiem jakos ugryźć tego. Jest jeszcze problem że w drogach z punktu do punktu postać może się zatrzymać i wtedy musiał by znowu zaznaczać ten punkt. Pomoże kto z tym? Przynajmniej cos zacząć to już dalej jakos pójdzie.

 

Global $Mark1 = 0x44CE57
Global $Mark2 = 0x0F0FFF
Global $Mark3 = 0xF50000

 

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Zaloguj się poniżej.

Zaloguj się
 Udostępnij

  • Ostatnio przeglądający forum Klikanie w punkty na mapie   0 użytkowników
    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...