Can you move the mouse in a random curved path?

Get help with using AutoHotkey and its commands and hotkeys
Hellbent
Posts: 723
Joined: 23 Sep 2017, 13:34

Re: Can you move the mouse in a random curved path?

24 Jun 2019, 23:27

You could also just record yourself moving your cursor to a button and pressing it.

Code: Select all

#SingleInstance,Force
SetBatchLines,-1
#NoEnv
CoordMode,Mouse,Screen
global Stop,positions:=[]
Gui,1:+AlwaysOnTop
Gui,1:Add,Edit,xm ym w200 r1 vMove_Count
Gui,1:Add,Button,xm y+20 w200 h30 gStop_Recording,Stop Recording
Gui,1:Show,,Mouse Recorder
return
GuiClose:
GuiContextMenu:
*ESC::
	ExitApp

Stop_Recording:
	Stop:=1
	return

*RButton Up::   ;<------------- Start Recording (Wait until the end of the countdown and then move to and press the button)
MouseTarck(){
	Positions:="",Positions:=[],CountDown(),Stop:=0,index:=1
	MouseGetPos,ox,oy
	Loop,	{
		MouseGetPos,cx,cy
		if(cx!=ox||cy!=oy){
			positions[1]:={X:cx,Y:cy}
			break
		}
	}
	;~ While(!Stop){
		;~ MouseGetPos,x,y
		;~ if(x!=positions[index].X||y!=positions[Index].Y)
			;~ positions[++index]:={X:x,Y:y}
		;~ GuiControl,1:,Move_Count,% Positions.Length()
	;~ }
	While(!Stop){
		MouseGetPos,x,y
		MouseMove,x,y,0
		positions[++index]:={X:x,Y:y}
		GuiControl,1:,Move_Count,% Positions.Length()
	}
	SoundBeep,500
}

*Numpad1::
	MouseMove,Positions[1].X,Positions[1].Y,0
	CountDown()
	Loop,% Positions.Length()	{
		MouseMove,Positions[A_Index].X, Positions[A_Index].Y,0
		GuiControl,1:,Move_Count,% A_Index
	}
	return

CountDown(){
	ToolTip,3
	Sleep,600
	ToolTip,2
	Sleep,600
	ToolTip,1
	Sleep,600
	ToolTip
}

I was surprised at how close my vector script matched how I actually move my hand.
User avatar
Mark2402
Posts: 11
Joined: 03 Jun 2019, 12:06

Re: Can you move the mouse in a random curved path?

25 Jun 2019, 14:38

Dude, I give up. This stuff is beyond me. I watched and read those three links, and learned little.
One thing I have learned. . . I always thought that Velocity is simply speed.
But with Vectors, velocity is speed (or length?) And direction. There. . . I learned something.
And I think that the Mag values in this script are lines of a certain length.
But then you mentioned that they are "acceleration amounts, added to the velocity of each frame".
I don't get that at all. And please don't waste your time trying to esplain it to me, Lucy. I'm just two dum! :oops:
Now to the task at hand. . . I Really Like the way that your script is now working.
Except. . . will you please make it slow down as it gets closer to the target?
Like a human might move a mouse pointer. Would you Please do that for me? :thumbup:
I think (hope) I will be able to figure out how to eliminate the ToolTips and the GUI.
I only want to give the Target coordinates to the script, and have it do its thing.
THANKS Very Much, Mr. Hellbent.
Hellbent mouse moves 12.jpg
Hellbent mouse moves 12.jpg (61.36 KiB) Viewed 405 times
User avatar
Mark2402
Posts: 11
Joined: 03 Jun 2019, 12:06

Re: Can you move the mouse in a random curved path?

25 Jun 2019, 14:46

OK,. . . What is that Mouse Recorder thing supposed to be doing?
What is supposed to be typed in the box?
Sorry, but I don't understand the purpose, there. :crazy:
User avatar
Mark2402
Posts: 11
Joined: 03 Jun 2019, 12:06

Re: Can you move the mouse in a random curved path?

25 Jun 2019, 14:52

It's only purpose is to record mouse movements?
But MS Paint does the same thing,. . . yes? :?:
DRocks
Posts: 512
Joined: 08 May 2018, 10:20

Re: Can you move the mouse in a random curved path?

01 Aug 2019, 12:02

I jump in and bump this post. Currently also thinking to implement mousemove randomization for a game script.
You guys are has Mark said : geniuses
DRocks
Posts: 512
Joined: 08 May 2018, 10:20

Re: Can you move the mouse in a random curved path?

02 Aug 2019, 19:08

hello guys, I've been experimenting with the two latest examples by @Hellbent and @wolf_II .

I've come up with another interesting way of testing the mouse randomization paths.
Please let me know how this can be better calculated (maths wise) and how we could sometimes fake a random curve to add humanity to this.

here's the code re-using bunch of your codes:

Code: Select all

#SingleInstance,Force
SetBatchLines,-1
#NoEnv
CoordMode, Mouse, Client
SetMouseDelay, 4
SetDefaultMouseSpeed, 0

; Create Gui
Gui, New, HWNDhGui -MinimizeBox, Randomize Mouse Movement
Gui, Color, Black
Gui, font, s20 cwhite

Gui, Add, Text, , What mode will F1 hotkey activate ?
Gui, Add, Radio, x+m vradioControl gGuiSubmit, Record my mouse moves
Gui, Add, Radio, gGuiSubmit, Generate mathematical mouse moves
Gui, Add, Checkbox, hidden checked xp y+30 vshowPerfectLine gGuiSubmit, Draw green perfect line ?
Gui, Add, Checkbox, hidden vshowStepByStepMoves gGuiSubmit, Show step by step mouse moves ?
Gui, Add, Text, hidden xm w200 r1 vMove_Count, Press F1 to start recording

Menu, Main, Add, Start  `tF1, Start
Menu, Main, Add, Stop  `tF2, StopRecord
Menu, Main, Add, Playback  `tF3, Playback
Menu, Main, Add, Reload  `tF4, Reload
Gui, Menu, Main

gW:=A_ScreenWidth//1.3
gH:=A_ScreenHeight//1.3
Gui, Show, w%gW% h%gH%

; Global variables
global hGui, Stop, positions:=[]
global G:= new GDI(hGui)
return

GuiSubmit:
Gui, Submit, NoHide
if (radioControl = 1) {
	GuiControl, Hide, showPerfectLine
	GuiControl, Hide, showStepByStepMoves
	GuiControl, Show, Move_Count
} else if (radioControl = 2) {
	GuiControl, Show, showPerfectLine
	GuiControl, Show, showStepByStepMoves
	GuiControl, Hide, Move_Count
}
return

Reload:
Reload
return

GuiClose:
GuiContextMenu:
*ESC::
ExitApp

StopRecord:
Stop:= 1
GuiControl, show, PlaybackRecording
GuiControl, hide, StopRecord
return

start:
if (radioControl = 1) {
	GuiControl, %hGui%:Show, Move_Count
	GuiControl, %hGui%:Show, StopRecord
	MouseTrack()
	
} else if (radioControl = 2) {
	; Starting pos (Point A)
	MouseGetPos, startX, startY
	
; Generate new ending pos (Point B)
	pointB_X1:=0, pointB_Y1:=0, pointB_X2:=gW-20, pointB_Y2:=gH-20 ; ending pos square limits
	,endX:=Random(pointB_X1, pointB_X2)
	,endY:=Random(pointB_Y1, pointB_Y2)
	
; Draw the straigt line in GREEN if the user has checked the check box control
	if (showPerfectLine) {
		G.DrawLine(startX, startY, endX, endY, 0x00ff00)
		G.BitBlt()
	}
	
; Calculate the average coordinates distance from pointA to pointB (in pixels)
	xPixelsDistance:= endX - startX
	yPixelsDistance:= endY - startY
	averagePixelsDistance:= abs(xPixelsDistance) + abs(yPixelsDistance) // 2
	
; Mouse behavior settings
	stepsPerPixels:= 0.03
	mouseMoveSteps:= Round(abs(averagePixelsDistance * stepsPerPixels))
	if (mouseMoveSteps = 0)
		mouseMoveSteps:= 1
	if (mouseMoveSteps > 15)
		mouseMoveSteps:= mouseMoveSteps // 1.1
	if (mouseMoveSteps > 20)
		mouseMoveSteps:= mouseMoveSteps // 1.3
	if (mouseMoveSteps > 25)
		mouseMoveSteps:= mouseMoveSteps // 1.5
	ToolTip, % "Steps: " mouseMoveSteps
	xIncrements:= xPixelsDistance/mouseMoveSteps
	yIncrements:= yPixelsDistance/mouseMoveSteps
	minVariation:= 2
	maxVariation:= 6
	
; Move the mouse and draw a white line for each step
	Loop, % mouseMoveSteps {
		
		if (showStepByStepMoves)
			Sleep, 150 ; delay to help visualize mouse path variation compared to straight line
		
	; Calculate the new cursor pos to which we'll move mouse
		addX := A_Index * xIncrements
		addY := A_Index * yIncrements
		
		newX := (startX + addX) + Random(-Random(minVariation, maxVariation), Random(minVariation, maxVariation))
		newY := (startY + addY) + Random(-Random(minVariation, maxVariation), Random(minVariation, maxVariation))
		
	; Draw the pixel corresponding to where the cursor is
		MouseGetPos, mX, mY
		G.DrawLine(mX, mY, newX, newY, 0xffffff)
		G.BitBlt()
		
		MouseMove, %newX%, %newY%, % (A_index = mouseMoveSteps ? Random(1,3):0)
	}
	
; Final mouse destination
	MouseGetPos, mX, mY
	G.DrawLine(mX, mY, endX, endY, 0xffffff)
	G.BitBlt()
	MouseMove, %endX%, %endY%, % Random(5,12)
	
} else {
	MsgBox Select the mode you want to use
}
return


Playback:
MouseMove,positions[1].X, positions[1].Y, 0 ; Move to recorded initial position
CountDown()
Loop, % positions.Length() {
	MouseMove, positions[A_Index].X, positions[A_Index].Y
	GuiControl, %hGui%:, Move_Count, % A_Index
}
return

;--------------------------------------------------------------------------------
MouseTrack() {
;--------------------------------------------------------------------------------
	G.__Delete()
	G:= new GDI(hGui)
	positions:=[]
	Stop:=0, index:=1
	CountDown()
	; Get initial mouse pos
	MouseGetPos, ox, oy
	prevX:=ox, prevY:=oy
	Loop, {
		MouseGetPos, cx, cy
		if (cx != prevX || cy != prevY) {
			positions[1]:= {X:cx, Y:cy}
			break
		}
	}
	; Get every Mouse Moves
	While(!Stop) {
		MouseGetPos, x, y
		MouseMove, x, y
		if (x != prevX or y != prevY) {
			positions[++index]:={X:x,Y:y}
			;G.DrawLine(prevX, PrevY, x, y, 0x00ff00)
			G.SetPixel(x, y, 0x00ff00)
			G.BitBlt()
			GuiControl, %hGui%:, Move_Count, % "Move count: " positions.Length()
			GuiControl, %hGui%:, StopRecord, Stop Recording
			prevX:=x, prevY:=y
		}
	}
	SoundBeep,500
}

;--------------------------------------------------------------------------------
CountDown() {
;--------------------------------------------------------------------------------
	ToolTip,3
	Sleep,600
	ToolTip,2
	Sleep,600
	ToolTip,1
	Sleep,600
	ToolTip
}

;--------------------------------------------------------------------------------
random(min, max) {
;--------------------------------------------------------------------------------
	Random, value, min, max
	return value
}


;===============================================================================
class GDI { ; from dwitter
;===============================================================================
    __New(hWnd, CliWidth=0, CliHeight=0) {
        if !(CliWidth && CliHeight) {
            VarSetCapacity(Rect, 16, 0)
            DllCall("GetClientRect", "Ptr", hWnd, "Ptr", &Rect)
            CliWidth := NumGet(Rect, 8, "Int")
            CliHeight := NumGet(Rect, 12, "Int")
        }
        this.CliWidth := CliWidth
        this.CliHeight := CliHeight
        this.hWnd := hWnd
        this.hDC := DllCall("GetDC", "UPtr", hWnd, "UPtr")
        this.hMemDC := DllCall("CreateCompatibleDC", "UPtr", this.hDC, "UPtr")
        this.hBitmap := DllCall("CreateCompatibleBitmap", "UPtr", this.hDC, "Int", CliWidth, "Int", CliHeight, "UPtr")
        this.hOriginalBitmap := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", this.hBitmap)
    }
	
    __Delete() {
        DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", this.hOriginalBitmap)
        DllCall("DeleteObject", "UPtr", this.hBitmap)
        DllCall("DeleteObject", "UPtr", this.hMemDC)
        DllCall("ReleaseDC", "UPtr", this.hWnd, "UPtr", this.hDC)
    }
	
    Resize(w, h) {
        this.CliWidth := w
        this.CliHeight := h
		
        this.hBitmap := DllCall("CreateCompatibleBitmap", "UPtr", this.hDC, "Int", w, "Int", h, "UPtr")
        hPrevBitmap := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", this.hBitmap)
        DllCall("DeleteObject", "UPtr", hPrevBitmap)
    }
	
    BitBlt(x=0, y=0, w=0, h=0) {
        w := w ? w : this.CliWidth
        h := h ? h : this.CliHeight
		
        DllCall("BitBlt", "UPtr", this.hDC, "Int", x, "Int", y
        , "Int", w, "Int", h, "UPtr", this.hMemDC, "Int", 0, "Int", 0, "UInt", 0xCC0020) ;SRCCOPY
    }
	
    DrawLine(x, y, x2, y2, Color) {
        Pen := new GDI.Pen(Color)
        DllCall("MoveToEx", "UPtr", this.hMemDC, "Int", this.TranslateX(x), "Int", this.TranslateY(y), "UPtr", 0)
        hOriginalPen := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Pen.Handle, "UPtr")
        DllCall("LineTo", "UPtr", this.hMemDC, "Int", this.TranslateX(x2), "Int", this.TranslateY(y2))
        DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalPen, "UPtr")
    }
	
    SetPixel(x, y, Color) {
        x := this.TranslateX(x)
        y := this.TranslateY(y, this.Invert) ; Move up 1 px if inverted (drawing "up" instead of down)
        DllCall("SetPixelV", "UPtr", this.hMemDC, "Int", x, "Int", y, "UInt", Color)
    }
	
    FillRectangle(x, y, w, h, Color, BorderColor=-1)	{
        if (w == 1 && h == 1)
            return this.SetPixel(x, y, Color)
		
        Pen := new this.Pen(BorderColor < 0 ? Color : BorderColor)
        Brush := new this.Brush(Color)
		
        ; Replace the original pen and brush with our own
        hOriginalPen := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Pen.Handle, "UPtr")
        hOriginalBrush := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Brush.Handle, "UPtr")
		
        x1 := this.TranslateX(x)
        x2 := this.TranslateX(x+w)
        y1 := this.TranslateY(y)
        y2 := this.TranslateY(y+h)
		
        DllCall("Rectangle", "UPtr", this.hMemDC
        , "Int", x1, "Int", y1
        , "Int", x2, "Int", y2)
		
        ; Reselect the original pen and brush
        DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalPen, "UPtr")
        DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalBrush, "UPtr")
    }
	
    FillEllipse(x, y, w, h, Color, BorderColor=-1)	{
        Pen := new this.Pen(BorderColor < 0 ? Color : BorderColor)
        Brush := new this.Brush(Color)
		
        ; Replace the original pen and brush with our own
        hOriginalPen := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Pen.Handle, "UPtr")
        hOriginalBrush := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Brush.Handle, "UPtr")
		
        x1 := this.TranslateX(x)
        x2 := this.TranslateX(x+w)
        y1 := this.TranslateY(y)
        y2 := this.TranslateY(y+h)
		
        DllCall("Ellipse", "UPtr", this.hMemDC
        , "Int", x1, "Int", y1
        , "Int", x2, "Int", y2)
		
        ; Reselect the original pen and brush
        DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalPen, "UPtr")
        DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalBrush, "UPtr")
    }
	
    TranslateX(X) {
        return Floor(X)
    }
	
    TranslateY(Y, Offset=0)	{
        if this.Invert
            return this.CliHeight - Floor(Y) - Offset
        return Floor(Y)
    }
	
    class Pen {
        __New(Color, Width=1, Style=0) {
            this.Handle := DllCall("CreatePen", "Int", Style, "Int", Width, "UInt", Color, "UPtr")
        }
		
        __Delete() {
            DllCall("DeleteObject", "UPtr", this.Handle)
        }
    }
	
    class Brush {
        __New(Color) {
            this.Handle := DllCall("CreateSolidBrush", "UInt", Color, "UPtr")
        }
		
        __Delete() {
            DllCall("DeleteObject", "UPtr", this.Handle)
        }
    }
}
Edit: BTW Wolf, ty so much for the Class GDI by dwitter. This is so much easier and fun to use than the other version i knew

Edit2: I realized that mathematical calculations of a human mouse move is f*g complex and over my skills by far. Maybe the idea of recording a few samples of the user's mouse moves could help generating commun behaviors more easily than starting from scratch ? if anyone is interested in this subject please share your insights i'm underwater :P

Return to “Ask For Help”

Who is online

Users browsing this forum: Bing [Bot], just me and 195 guests