鼠标拖动 - C# 机器人

Mouse Drag - C# bot

第一次这样做。我目前正在使用 C# 构建一个机器人,并希望我的机器人能够以一种看起来像人类的方式将鼠标移动到给定点。我指的是当人们将光标移动到他们试图点击的点时鼠标的拖动。目前,我的 C# 机器人会立即将鼠标移动到看起来不像人类的位置。

private static Point[] FindColor(Color color)
{
    int searchValue = color.ToArgb();
    List<Point> result = new List<Point>();
    using (Bitmap bmp = GetScreenShot())
    {
        for (int x = 0; x < bmp.Width; x++)
        {
            for (int y = 0; y < bmp.Height; y++)
            {
                if (searchValue.Equals(bmp.GetPixel(x, y).ToArgb()))
                    result.Add(new Point(x, y));
            }
        }
    }
    return result.ToArray();
}


// FUNCTIONS OCCUR BELOW
// Error message if program could not find bitmap within screenshot show error message

Color myRgbColor = new Color(); // Creates new colour called myRgbColor
myRgbColor = Color.FromArgb(51, 90, 9); // This colour equals the RGB value
Point[] points = FindColor(myRgbColor); // Create an array called points which list all the points found in the screen where the RgB value matches.
if (points.Length > 0)
{
    Cursor.Position = points[2]; // Move mouse cursor to first point (Point 0)
    Thread.Sleep(0200);
    MouseClick();
}
if (points.Length == 0)
{
    MessageBox.Show("No matches!"); // Return error
    goto checkore;
}

您将要使用某种带有回调的计时器,逐步移动鼠标。至于机芯本身,您拥有无限可能,但这全是数学。

所以,让我们分解问题。

什么是自然的鼠标移动?

位置变化率

它不一定看起来像,但是当您移动鼠标时,您只是每秒多次设置它的位置。

每秒位置变化的次数相当于鼠标的轮询率。 USB 鼠标的默认轮询速率是 125Hz(或者每秒 125 次位置变化,如果您愿意的话)。这是我们将用于我们的计时器的值:它的回调每秒将被调用 125 次。

var timer = new Timer(1000 / 125d);
timer.Elapsed += MoveMouse;

void MoveMouse(object sender, ElpasedEventArgs e) { }

速度和加速度

当你移动鼠标时,两个光标位置之间的距离不是恒定的,因为当你开始移动鼠标时你很快,但是当你靠近你想要光标移动的项目时你会变慢上。

根据context/mood:

我个人通常有两种移动鼠标的方式
  1. 一个快速均匀的移动接近目的地,然后一个缓慢的修正并继续前进(我通常会在第一次移动时经过目的地)
  2. 一个中慢速运动,减速较小,最后减速较大

整体移动速度还取决于三个因素:

  1. 您的光标与目的地之间的距离
  2. 目标区域的大小
  3. 你的个人速度

我完全不知道如何根据这些因素得出公式,这将是你自己反复试验的工作。

这一个纯粹是基于数学和观察的,如果有的话,要完全正确是很棘手的;每个人移动鼠标的方式都不一样。

我可以为您提供的解决方案是简单地忘记减速、校正等,将您的运动分成相等的步数。优点就是简单

using System;
using System.Timers;
using System.Drawing;

public class Program
{
    static int stepCount = 0;
    static int numberOfSteps = 0;
    static float stepDistanceX = 0;
    static float stepDistanceY = 0;
    static PointF destinationPoint;
    static Timer timer;

    public static void Main()   
    {
        int timerStepDurationMs = 1000 / 125;

        PointF currentPoint = Cursor.Position;
        destinationPoint = new PointF(2000, 1800); // or however you select your point

        int movementDurationMs = new Random().Next(900, 1100); // roughly 1 second
        int numberOfSteps = movementDurationMs / timerStepDurationMs;

        stepDistanceX = (destinationPoint.X - currentPoint.X) / (float)numberOfSteps;
        stepDistanceY = (destinationPoint.Y - currentPoint.Y) / (float)numberOfSteps;

        timer = new Timer(timerStepDurationMs);
        timer.Elapsed += MoveMouse;
        timer.Start();

        while (stepCount != numberOfSteps) { }
    }

    static void MoveMouse(object sender, ElapsedEventArgs e)
    {
        stepCount++;

        if (stepCount == numberOfSteps)
        {
            Cursor.Position = destinationPoint;
            timer.Stop();
        }

        Cursor.Position.X += stepDistanceX;
        Cursor.Position.Y += stepDistanceY;
    }
}

请注意,我没有使用 "Cursor" 进行测试,而是使用了一些 PointF 变量。它在这里似乎工作正常:dotnetfiddle.