Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz
  • 0

Klikanie w punkty na mapie


Adrstalik

Pytanie

Opublikowano

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

 

Kocham mpcforum.pl!!!

18706.png

22 odpowiedzi na to pytanie

Rekomendowane odpowiedzi

Opublikowano

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

Opublikowano

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.

 

 

Opublikowano

Adstralik a tobie wszystko od razu dobrze działało czy musiałeś coś zmieniać? Bo mi też to nie działa.

reklama

Opublikowano

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. 

 

 

 

Opublikowano

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. 

 

 

 

Opublikowano

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. ;)

Kocham mpcforum.pl!!!

18706.png

Opublikowano

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

 

Opublikowano

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

 

 

 

Opublikowano

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

 

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...