Java机器人类模拟人类鼠标移动



我正在做一个关于远程控制的项目,将光标的坐标x和y从客户端发送到服务器。

但是

robot.mouseMove(x,y);

将只将光标移动到特定点,而不将光标从原始点移动

我找到了这个简单的算法来模拟鼠标的连续运动

for (int i=0; i<100; i++){
   int x = ((end_x * i)/100) + (start_x*(100-i)/100);
 int y = ((end_y * i)/100) + (start_y*(100-i)/100);
 robot.mouseMove(x,y);
} 

但这个算法仍然太简单了,它只是从一个点缓慢地移动到另一个点,这仍然不像人类的行为。

我从网上读了一些关于遥控器的开放源码,我发现了这个项目http://code.google.com/p/java-remote-control/正在使用MouseListener类中调用MosueMovement的方法,他们用它来执行"拖动"。

我想知道有谁知道做这件事的更好方法吗?

如果你想让人工运动变得自然,我认为有几件事需要考虑:

  1. 人类鼠标的运动通常呈轻微的弧形,因为鼠标的手围绕手腕旋转。此外,这种弧线在水平运动中比在垂直运动中更明显
  2. 人类倾向于朝着大致的方向前进,经常超过目标,然后回到实际目标
  3. 朝向目标的初始速度相当快(因此出现了上述过冲),然后对于精确瞄准来说稍微慢一点。但是,如果光标最初靠近目标,则不会快速移动(过冲也不会)

不过,这在算法中有点复杂。

对于未来的任何人:我为Java开发了一个库,它模仿了人类的鼠标移动。运动中的噪音/锯齿、正弦弧、位置有点超调等。此外,该库的编写考虑到了扩展和配置的可能性,因此如果默认解决方案与情况不匹配,任何人都可以对其进行微调。现在可从Maven Central获得。

https://github.com/JoonasVali/NaturalMouseMotion

看看我写的这个例子。你可以改进它来模拟乔伊说的话。我写得很快,有很多东西可以改进(算法和类设计)。请注意,我只处理从左到右的动作。

import java.awt.AWTException;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Robot;
public class MouseMoving {
    public static void main(String[] args) {
        new MouseMoving().execute();
    }
    public void execute() {
        new Thread( new MouseMoveThread( 100, 50, 50, 10 ) ).start();
    }
    private class MouseMoveThread implements Runnable {
        private Robot robot;
        private int startX;
        private int startY;
        private int currentX;
        private int currentY;
        private int xAmount;
        private int yAmount;
        private int xAmountPerIteration;
        private int yAmountPerIteration;
        private int numberOfIterations;
        private long timeToSleep;
        public MouseMoveThread( int xAmount, int yAmount,
                int numberOfIterations, long timeToSleep ) {
            this.xAmount = xAmount;
            this.yAmount = yAmount;
            this.numberOfIterations = numberOfIterations;
            this.timeToSleep = timeToSleep;
            try {
                robot = new Robot();
                Point startLocation = MouseInfo.getPointerInfo().getLocation();
                startX = startLocation.x;
                startY = startLocation.y;
            } catch ( AWTException exc ) {
                exc.printStackTrace();
            }
        }
        @Override
        public void run() {
            currentX = startX;
            currentY = startY;
            xAmountPerIteration = xAmount / numberOfIterations;
            yAmountPerIteration = yAmount / numberOfIterations;
            while ( currentX < startX + xAmount &&
                    currentY < startY + yAmount ) {
                currentX += xAmountPerIteration;
                currentY += yAmountPerIteration;
                robot.mouseMove( currentX, currentY );
                try {
                    Thread.sleep( timeToSleep );
                } catch ( InterruptedException exc ) {
                    exc.printStackTrace();
                }
            }
        }
    }
}

最新更新