使鼠标移动像人类一样(使用弧线而不是直线到达目的地)

发布于 2024-12-21 16:26:52 字数 3388 浏览 5 评论 0原文

我正在使用 java.awt.Robot 制作自动答题器。然而,我担心的问题之一是这些动作不太像人类。谁能建议对我的代码进行一些更改,使其更加人性化?现在它只是沿直线移动。

/**
 * 
 * @param robot The java.awt.Robot being utilized
 * @param sx The start x position of the mouse
 * @param sy The start y potition of the mouse
 * @param ex The end x position of the mouse
 * @param ey The end y position of the mouse
 * @param speed The speed at which to travel
 */
public void moveMouse(Robot robot, int sx, int sy, int ex, int ey, int speed){
    for (int i=0; i<100; i++){  
        int mov_x = ((ex * i)/100) + (sx*(100-i)/100);
        int mov_y = ((ey * i)/100) + (sy*(100-i)/100);
        robot.mouseMove(mov_x,mov_y);
        robot.delay(speed);
    }

}

更新: 我决定采用一种利用贝塞尔曲线的算法。自从我实施这一更改以来已经很长时间了,但我想将其发布在这里,以防人们将来发现它有用。这是我最终得到的结果:

public class MouseEvent{
    public int getMouseX(){
        return MouseInfo.getPointerInfo().getLocation().x;
    }

    public int getMouseY(){
        return MouseInfo.getPointerInfo().getLocation().y;
    }

    public void moveMouse(int speed, int destX, int destY, int ranX, int ranY){
        Mouse.moveMouse(new Robot(), new Point(getMouseX(),getMouseY()), new Point(destX, destY), speed, ranX, ranY);
    }
}

public class Mouse {
    public static void moveMouse(Robot robot, Point s, Point e, int speed, int ranX, int ranY){
        if(Math.abs(e.x-s.x) <= ranX && Math.abs(e.y-s.y) <= ranY)
            return;

        Point[] cooardList;
        double t;    //the time interval
        double k = .025;
        cooardList = new Point[4];

        //set the beginning and end points
        cooardList[0] = s;
        cooardList[3] = new Point(e.x+random(-ranX,ranX),e.y+(random(-ranY,ranY)));

        int xout = (int)(Math.abs(e.x - s.x) /10);
        int yout = (int)(Math.abs(e.y - s.y) /10);

        int x=0,y=0;

        x = s.x < e.x 
            ? s.x + ((xout > 0) ? random(1,xout) : 1)
            : s.x - ((xout > 0) ? random(1,xout) : 1);
        y = s.y < e.y 
            ? s.y + ((yout > 0) ? random(1,yout) : 1)
            : s.y - ((yout > 0) ? random(1,yout) : 1);
        cooardList[1] = new Point(x,y);

        x = e.x < s.x 
            ? e.x + ((xout > 0) ? random(1,xout) : 1)
            : e.x - ((xout > 0) ? random(1,xout) : 1);
        y = e.y < s.y 
            ?  e.y + ((yout > 0) ? random(1,yout) : 1)
            : e.y - ((yout > 0) ? random(1,yout) : 1);
        cooardList[2] = new Point(x,y);

        double px = 0,py = 0;
        for(t=k;t<=1+k;t+=k){
            //use Berstein polynomials
            px=(cooardList[0].x+t*(-cooardList[0].x*3+t*(3*cooardList[0].x-
                cooardList[0].x*t)))+t*(3*cooardList[1].x+t*(-6*cooardList[1].x+
                cooardList[1].x*3*t))+t*t*(cooardList[2].x*3-cooardList[2].x*3*t)+
                cooardList[3].x*t*t*t;
            py=(cooardList[0].y+t*(-cooardList[0].y*3+t*(3*cooardList[0].y-
                cooardList[0].y*t)))+t*(3*cooardList[1].y+t*(-6*cooardList[1].y+
                cooardList[1].y*3*t))+t*t*(cooardList[2].y*3-cooardList[2].y*3*t)+
                cooardList[3].y*t*t*t;
            robot.mouseMove((int)px, (int)py);
            robot.delay(random(speed,speed*2));
        }
    }    
}

I am making and auto clicker using java.awt.Robot. One of the concerns i have however is the movements aren't very humanlike. Can anyone suggest some changes to my code to make it more human like? Right now it just moves in a straight line.

/**
 * 
 * @param robot The java.awt.Robot being utilized
 * @param sx The start x position of the mouse
 * @param sy The start y potition of the mouse
 * @param ex The end x position of the mouse
 * @param ey The end y position of the mouse
 * @param speed The speed at which to travel
 */
public void moveMouse(Robot robot, int sx, int sy, int ex, int ey, int speed){
    for (int i=0; i<100; i++){  
        int mov_x = ((ex * i)/100) + (sx*(100-i)/100);
        int mov_y = ((ey * i)/100) + (sy*(100-i)/100);
        robot.mouseMove(mov_x,mov_y);
        robot.delay(speed);
    }

}

Update:
I decided to go with an algorithm that makes use of Bézier Curves. It's been a very long time since I implemented the change, but I wanted to post it here just in case people would find it useful in the future. Here is what I ended up with:

public class MouseEvent{
    public int getMouseX(){
        return MouseInfo.getPointerInfo().getLocation().x;
    }

    public int getMouseY(){
        return MouseInfo.getPointerInfo().getLocation().y;
    }

    public void moveMouse(int speed, int destX, int destY, int ranX, int ranY){
        Mouse.moveMouse(new Robot(), new Point(getMouseX(),getMouseY()), new Point(destX, destY), speed, ranX, ranY);
    }
}

public class Mouse {
    public static void moveMouse(Robot robot, Point s, Point e, int speed, int ranX, int ranY){
        if(Math.abs(e.x-s.x) <= ranX && Math.abs(e.y-s.y) <= ranY)
            return;

        Point[] cooardList;
        double t;    //the time interval
        double k = .025;
        cooardList = new Point[4];

        //set the beginning and end points
        cooardList[0] = s;
        cooardList[3] = new Point(e.x+random(-ranX,ranX),e.y+(random(-ranY,ranY)));

        int xout = (int)(Math.abs(e.x - s.x) /10);
        int yout = (int)(Math.abs(e.y - s.y) /10);

        int x=0,y=0;

        x = s.x < e.x 
            ? s.x + ((xout > 0) ? random(1,xout) : 1)
            : s.x - ((xout > 0) ? random(1,xout) : 1);
        y = s.y < e.y 
            ? s.y + ((yout > 0) ? random(1,yout) : 1)
            : s.y - ((yout > 0) ? random(1,yout) : 1);
        cooardList[1] = new Point(x,y);

        x = e.x < s.x 
            ? e.x + ((xout > 0) ? random(1,xout) : 1)
            : e.x - ((xout > 0) ? random(1,xout) : 1);
        y = e.y < s.y 
            ?  e.y + ((yout > 0) ? random(1,yout) : 1)
            : e.y - ((yout > 0) ? random(1,yout) : 1);
        cooardList[2] = new Point(x,y);

        double px = 0,py = 0;
        for(t=k;t<=1+k;t+=k){
            //use Berstein polynomials
            px=(cooardList[0].x+t*(-cooardList[0].x*3+t*(3*cooardList[0].x-
                cooardList[0].x*t)))+t*(3*cooardList[1].x+t*(-6*cooardList[1].x+
                cooardList[1].x*3*t))+t*t*(cooardList[2].x*3-cooardList[2].x*3*t)+
                cooardList[3].x*t*t*t;
            py=(cooardList[0].y+t*(-cooardList[0].y*3+t*(3*cooardList[0].y-
                cooardList[0].y*t)))+t*(3*cooardList[1].y+t*(-6*cooardList[1].y+
                cooardList[1].y*3*t))+t*t*(cooardList[2].y*3-cooardList[2].y*3*t)+
                cooardList[3].y*t*t*t;
            robot.mouseMove((int)px, (int)py);
            robot.delay(random(speed,speed*2));
        }
    }    
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

庆幸我还是我 2024-12-28 16:26:52
 public void moveMouse(int sx, int sy, int ex, int ey, int speed) throws AWTException {
        Robot robot = new Robot();
        int a = 10;
        boolean flag = true;
        for (int i = 0; i < 100; i++) {
            int mov_x = ((ex * i) / 100) + (sx * (100 - i) / 100);
            int mov_y = ((ey * i) / 100) + (sy * (100 - i) / 100);
            if (flag == true) {
                robot.mouseMove(mov_x + a, mov_y); // adds 10 to X-axis
                flag = false;
            } else {
                robot.mouseMove(mov_x - 2 * a, mov_y); // subtracts 20 to X-axis
                flag = true;
            }
            robot.delay(speed);
        }
    }

只是操纵了你的代码。这将沿 X 方向的直线路径移动鼠标。你可以从这里实现你想要的。只是得到想法。如果您可以操作 mov_xmov_y ,您可以按照您想要的方式移动。

 public void moveMouse(int sx, int sy, int ex, int ey, int speed) throws AWTException {
        Robot robot = new Robot();
        int a = 10;
        boolean flag = true;
        for (int i = 0; i < 100; i++) {
            int mov_x = ((ex * i) / 100) + (sx * (100 - i) / 100);
            int mov_y = ((ey * i) / 100) + (sy * (100 - i) / 100);
            if (flag == true) {
                robot.mouseMove(mov_x + a, mov_y); // adds 10 to X-axis
                flag = false;
            } else {
                robot.mouseMove(mov_x - 2 * a, mov_y); // subtracts 20 to X-axis
                flag = true;
            }
            robot.delay(speed);
        }
    }

Just manipulated your code. This moves the mouse in straight path in X-direction. You can achieve what you want from here. Just get the ideas. You can move any way you want if you can manipulate mov_x and mov_y .

酒浓于脸红 2024-12-28 16:26:52

您可以使用 Catmull-Rom 方法。在端点周围的某处(可能是直线所在的位置)生成随机控制点,询问从开始到结束的每个步骤的坐标(参数 t,从零到一)。

请参阅演示小程序和源:http://www.cse.unsw.edu.au /~兰伯特/样条线/

You could use Catmull-Rom method. Generate random controlpoints somewhere around the endpoints and maybe where the straight line would be, asking for coordinates on every step moving from start to end (parameter t, from zero to one).

See demo applets and source: http://www.cse.unsw.edu.au/~lambert/splines/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文