Skocz do zawartości
Zaloguj się, aby obserwować  
Adrstalik

Klikanie w punkty na mapie

Polecane posty

Autor tematu Napisano (edytowany)

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

 

Edytowano przez Adrstalik
literówka

Udostępnij ten post


Link to postu
Pani Kasia

Proponuje podzielic mape na 4 czesci. Przed wykonaniem ruchu zapisac do ktorej cwiartki idziemy albo ktora cwiartke chcemy ignorowac. Gdy postac dojdzie do wyznaczonego punktu to kolejnego nie szukamy w ignorowanej czesci. 

 

Udostępnij ten post


Link to postu
Autor tematu Napisano

@Pawellek

A czy skrypt nie zatnie się w takim wypadku? : 

 

error.png

W 2 ćwiartce mamy 2 punkty. Skrypt bez przerwy wyszukiwałby tych dwóch punktów.

 

Udostępnij ten post


Link to postu

To wystarczy napisać funkcje która wyznaczy najblizszy punk wzgledem srodka ukladu (czyt. Twojej postaci).

Udostępnij ten post


Link to postu
Autor tematu Napisano

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ś? 

Udostępnij ten post


Link to postu

Ciezko jest zrozumiec co autor kodu mial na mysli. Jutro jak wroce z pracy to wrzuce jakis prototyp rozwiazania, bo rozkmina tego co tu sie dzieje zajelaby chyba wiecej czasu niz napisanie tego od zera. 

 

Udostępnij ten post


Link to postu
Autor tematu Napisano

Mamy cztery ćwiartki, każdą ćwiartkę przeszukuje w pionie i poziomie. Kiedy znajdzie powinien w danej ćwiartce kliknąć w ten pixel. Teoretycznie działa, praktycznie... Stąd jesteśmy tutaj. ;)

Udostępnij ten post


Link to postu

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.

Udostępnij ten post


Link to postu
Autor tematu Napisano (edytowany)

Kod generalnie działa. Ale jest problem w momencie, gdy postać znajduje się na miejscu czerwonego znacznika. 

przykład2.gif

Mysz powraca na środek mapy (czyli obecny punkt).

Edytowano przez Adrstalik

Udostępnij ten post


Link to postu

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

 

Udostępnij ten post


Link to postu

Bądź aktywny! Zaloguj się lub utwórz konto

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

Utwórz konto

Zarejestruj nowe konto, to proste!

Zarejestruj nowe konto

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się

Zaloguj się, aby obserwować  
  • Kto przegląda   0 użytkowników

    Brak zalogowanych użytkowników przeglądających tę stronę.


×