Jump to content

Mouse Follow Line


Recommended Posts

This is my first REAL program in autoit, and it was quite difficult. First of all, I just wanted something fast so i just scribbled a line on Paint, and set the mouse to go to the first pixel of the line. I hope you we can figure whats wrong with it without the line. This program searches for a black pixel around the current pixel, and checks to see that the mouse does not back track up the line.

global $paused
hotkeyset("s", "start")
hotkeyset("e", "terminate")
hotkeyset("p", "togglepause")
while 1
    sleep(50)
WEnd

func start()
    dim $xprev=243, $yprev=311, $nextpixels[9]
    winactivate("untitled - Paint")
    $xstart = 222
    $ystart = 144
    mousemove($xstart, $ystart, 5)
    ;$mouse=mousegetpos()
    ;msgbox(0, "Position", "X:" & $mouse[0] & "  Y:" & $mouse [1])
    ;$color=pixelgetcolor($mouse[0], $mouse[1])
    ;msgbox(0, "Color", "The color under the mouse is:" & $color)
    Do
    $nextpixels[4]=getnextpixel($xstart, $ystart, $xprev, $yprev)
    $xstart=$nextpixels[0]
    $ystart=$nextpixels[1]
    mousemove($xstart,$ystart, 5)
    $xprev=$nextpixels[2]
    $xprev=$nextpixels[3]
    Until $nextpixels=0
Exit
EndFunc

Func Terminate()
    tooltip("Program is being terminated", 0, 0)
    sleep(1500)
    Exit 0
    
EndFunc


Func TogglePause()
    $Paused = NOT $Paused
    While $Paused
        sleep(100)
        ToolTip('Script is "Paused"',0,0)
    WEnd
    ToolTip("")
EndFunc

func getnextpixel($xpixel, $ypixel, $prevx, $prevy)
    ;establish pixel variables
    dim $pixelcolor[8]
    dim $nextpixel[4]
    
    ;establish pixel coordinates of all the squares around the curring pixel
    
    ;Upper Right Pixel
    $pixeluprightx=$xpixel+1
    $pixeluprighty=$ypixel+1
    
    ;Right Pixel
    $pixelrightx=$xpixel+1
    $pixelrighty=$ypixel
    
    ;Bottom Right Pixel
    $pixelbotrightx=$xpixel+1
    $pixelbotrighty=$ypixel-1
    
    ;Bottom Pixel
    $pixelbotx=$xpixel
    $pixelboty=$ypixel-1
    
    ;Bottom Left Pixel
    $pixelbotleftx=$xpixel-1
    $pixelbotlefty=$ypixel-1
    
    ;Left Pixel
    $pixelleftx=$xpixel-1
    $pixellefty=$ypixel
    
    ;Top Left Pixel
    $pixelupleftx=$xpixel-1
    $pixeluplefty=$ypixel+1
    
    ;Top Pixel
    $pixelupx=$xpixel
    $pixelupy=$ypixel+1
    
    ;"check if any of adjoining pixels are black, and are not the current or previous pixel"
    $pixelcolor[0]=pixelgetcolor($pixelbotrightx,$pixelbotrighty)
    $pixelcolor[1]=PixelGetColor($pixelrightx, $pixelrighty)
    $pixelcolor[2]=PixelGetColor($pixelbotrightx, $pixelbotrighty)
    $pixelcolor[3]=PixelGetColor($pixelbotx, $pixelboty)
    $pixelcolor[4]=PixelGetColor($pixelbotleftx,$pixelbotlefty)
    $pixelcolor[5]=PixelGetColor($pixelleftx,$pixellefty)
    $pixelcolor[6]=PixelGetColor($pixelupleftx, $pixeluplefty)
    $pixelcolor[7]=PixelGetColor($pixelupx,$pixelupy)
    
Select  
Case $pixelcolor[0]=0 and $pixeluprightx <> $prevx and $pixeluprighty <> $prevy
    $nextpixel[0]=$pixeluprightx
    $nextpixel[1]=$pixeluprighty
    $nextpixel[2]=$xpixel
    $nextpixel[3]=$ypixel
    return $nextpixel
Case $pixelcolor[1]=0 and $pixelrightx <> $prevx and $pixelrighty <> $prevy
    $nextpixel[0]=$pixelrightx
    $nextpixel[1]=$pixelrighty
    $nextpixel[2]=$xpixel
    $nextpixel[3]=$ypixel
    return $nextpixel
Case $pixelcolor[2]=0 and $pixelbotrightx <> $prevx and $Pixelbotrighty <> $prevy
    $nextpixel[0]=$pixelbotrightx
    $nextpixel[1]=$pixelbotrighty
    $nextpixel[2]=$xpixel
    $nextpixel[3]=$ypixel
    return $nextpixel
Case $pixelcolor[3]=0 and $pixelbotx <> $prevx and $pixelboty <> $prevy
    $nextpixel[0]=$pixelbotx
    $nextpixel[1]=$pixelboty
    $nextpixel[2]=$xpixel
    $nextpixel[3]=$ypixel
    return $nextpixel
Case $pixelcolor[4]=0 and $pixelbotleftx <> $prevx and $pixelbotlefty <>$prevy
    $nextpixel[0]=$pixelbotleftx
    $nextpixel[1]=$pixelbotlefty
    $nextpixel[2]=$xpixel
    $nextpixel[3]=$ypixel
    return $nextpixel
Case $pixelcolor[5]=0 and $pixelleftx <> $prevx and $pixellefty <>$prevy
    $nextpixel[0]=$pixelleftx
    $nextpixel[1]=$pixellefty
    $nextpixel[2]=$xpixel
    $nextpixel[3]=$ypixel
    return $nextpixel
Case $pixelcolor[6]=0 and $pixelupleftx <> $prevx and $pixeluplefty <> $prevy
    $nextpixel[0]=$pixelupleftx
    $nextpixel[1]=$pixeluplefty
    $nextpixel[2]=$xpixel
    $nextpixel[3]=$ypixel
    return $nextpixel
Case $pixelcolor[7]=0 and $pixelupx <> $prevx and $pixelupy <> $prevy
    $nextpixel[0]=$pixelupx
    $nextpixel[1]=$pixelupy
    $nextpixel[2]=$xpixel
    $nextpixel[3]=$ypixel
    return $nextpixel   
Case Else
    return 0
endselect
EndFunc

The commented part in the top, was so i could see if the pixel was the right color. The autoit window information tells me that the pixel at the starting coordinate is 0 in decimal, but when i run the program with the commented portion uncommented, it tells me that the pixel color at that coordinate is 16777215, could this be a problem? I ran the program with all the cases set to 16777215 and it moved the mouse to the top left of the screen and kept it there so i couldn't move it.

Infinity is a floorless room without walls or ceiling.Anyone who cannot cope with mathematics is not fully human. At best he is a tolerable subhuman who has learned to wear shoes, bathe, and not make messes in the house.

Link to comment
Share on other sites

Nice project, too bad it doesn't work. It's a problem that can be solved in many ways.

Put it down for a few hours then isolate the problem, I'm sure you can do this on your own!

Edit: " tells me that the pixel color at that coordinate is 16777215"

16777215 is the decimal value of 0xFFFFFF, which is White. You're not following your line but a white pixel, which is probably found earliest at 0,0.

Edited by Manadar
Link to comment
Share on other sites

it starts and the mouse goes to the beginning of the line.. and i made it display a msgbox of what the next coordinate is before it goes there, and it just says the next coordinate is (0,0) and i don't know why

Infinity is a floorless room without walls or ceiling.Anyone who cannot cope with mathematics is not fully human. At best he is a tolerable subhuman who has learned to wear shoes, bathe, and not make messes in the house.

Link to comment
Share on other sites

Here's my solution, use it as a example:

If 2 pixels are found, backtracking may fail and your mouse will get stuck.

;Create the hotkeys, in case something goes wrong there is a exit func
HotKeySet("{ESC}", "MyExit")
HotKeySet("{SPACE}", "Start")

; Wait until you're allowed to start.
Global $Start

While Not $Start
WEnd

;Get the first black pixel near the mouse.
While 1
    $Pos = MouseGetPos()
    $Pos = PixelSearch($Pos[0]-5,$Pos[1]-5,$Pos[0]+5,$Pos[1]+5,0,50)
    If not @error Then
        ExitLoop
    EndIf
WEnd
$LineColor = PixelGetColor($Pos[0],$Pos[1])
MouseMove($Pos[0],$Pos[1],0)
;The first position is now found: Continue

;Make a variable for backtracking
Global $Last[2] = [$Pos[0],$Pos[1]]
While 1
    ;8 possible next entries every time, check them all
    Dim $Color[8][3]

    $Color[0][1] = $Pos[0]
    $Color[0][2] = $Pos[1]+1
    $Color[0][0] = PixelGetColor($Pos[0],$Pos[1]+1)
    $Color[1][1] = $Pos[0]
    $Color[1][2] = $Pos[1]-1
    $Color[1][0] = PixelGetColor($Pos[0],$Pos[1]-1)

    $Color[2][1] = $Pos[0]+1
    $Color[2][2] = $Pos[1]
    $Color[2][0] = PixelGetColor($Pos[0]+1,$Pos[1])
    $Color[3][1] = $Pos[0]-1
    $Color[3][2] = $Pos[1]
    $Color[3][0] = PixelGetColor($Pos[0]-1,$Pos[1])

    $Color[4][1] = $Pos[0]+1
    $Color[4][2] = $Pos[1]+1
    $Color[4][0] = PixelGetColor($Pos[0]+1,$Pos[1]+1)
    $Color[5][1] = $Pos[0]-1
    $Color[5][2] = $Pos[1]+1
    $Color[5][0] = PixelGetColor($Pos[0]-1,$Pos[1]+1)
    $Color[6][1] = $Pos[0]+1
    $Color[6][2] = $Pos[1]-1
    $Color[6][0] = PixelGetColor($Pos[0]+1,$Pos[1]-1)
    $Color[7][1] = $Pos[0]-1
    $Color[7][2] = $Pos[1]-1
    $Color[7][0] = PixelGetColor($Pos[0]-1,$Pos[1]-1)

    For $x = 0 to 7
        ; If the color found matches the color of the line 
        If ($Color[$x][0] = $LineColor) Then
            ; If the matched color is at a position different then the last pixel
            If (($Color[$x][1] <> $Last[0]) OR ($Color[$x][2] <> $Last[1])) Then
                ;Found possible match: This is new, now moving.
                MouseMove($Color[$x][1],$Color[$x][2],0)
                ;Make sure variables are updated for backtracking, and it is prepared for the next entry
                $Last[0] = $Pos[0]
                $Last[1] = $Pos[1]
                $Pos[0] = $Color[$x][1]
                $Pos[1] = $Color[$x][2]
                ExitLoop
            Else
                ;Found possible match: Already been there
            EndIf
        EndIf
        If $x = 7 Then
            ;The end of the loop has been reached while no possible entries
            ;have exited the loop, this is the end of the line.
            
            ;Remove the last known pixel so it will go back
            $Last[0] = -1
            $Last[1] = -1
            ;Exit       ;uncomment this line if you want it to exit when it reaches the end
        EndIf
    Next
WEnd

Func MyExit()
    Exit
EndFunc

Func Start()
    $Start = True
EndFunc

Edit: Sorry if you're not good with arrays, i just can't script without them.

Edit2: Update now so it goes back when it reaches the end of the line.

Edited by Manadar
Link to comment
Share on other sites

Thanks Manadar, the mouse follows the line perfectly, but i found where there was a semi-sharp turn in the line, that the mouse ended up going back to the end of the line, maybe because there are no pixels adjoining the turn to the line?

Infinity is a floorless room without walls or ceiling.Anyone who cannot cope with mathematics is not fully human. At best he is a tolerable subhuman who has learned to wear shoes, bathe, and not make messes in the house.

Link to comment
Share on other sites

That is actually because it doesn't backtrack every pixel. I have only not allowed to go back to the last pixel, so when there are 2 possible pixel choices there is a possibility that he will go in a endless loop, or go back as in this case.

What would be great if you could check the next position with all the previous positions. Then, at the end of the line Dim the entire array containing positions it has been, or Exit.

Edited by Manadar
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...