10

我正在做一个关于远程控制的项目,将光标的 conrdinate 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 的方法,他们使用它来执行“拖动”。

我想知道有没有人知道这样做的更好方法?

4

3 回答 3

10

如果你想让人工动作自然,我认为有几点需要考虑:

  1. 人类鼠标的移动通常是轻微的弧线,因为鼠标手围绕手腕旋转。此外,水平运动的弧线比垂直运动更明显。
  2. 人类倾向于朝着大方向前进,经常越过目标,然后又回到实际目标。
  3. 朝向目标的初始速度非常快(因此出现了前面提到的过冲),然后为了精确瞄准而稍慢一些。但是,如果光标最初靠近目标,则不会发生快速移动(也不会发生过冲)。

不过,这在算法中制定起来有点复杂。

于 2012-08-26T15:46:12.460 回答
6

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

https://github.com/JoonasVali/NaturalMouseMotion

于 2018-10-20T22:20:02.323 回答
5

看看我写的这个例子。您可以对此进行改进以模拟 Joey 所说的内容。我写得很快,有很多地方可以改进(算法和类设计)。请注意,我只处理从左到右的运动。

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();
                }

            }

        }

    }

}
于 2012-08-26T15:59:00.937 回答