微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

旋转记录的鼠标移动 [Java]

如何解决旋转记录的鼠标移动 [Java]

我创建了一个有趣的小项目,目的是记录我所做的自然鼠标移动,然后播放它,但将其对准目标。

问题:假设我制作并记录了一个以 x: 250,y: 278 结束的自然运动,现在我想要的是使自然运动记录在目标坐标处结束我指定(例如:x:100,y:100)。

现在是代码:(请注意代码并不干净,但如果我可以这么说,它只是第一个原型,因此请在阅读时记住这一点)。

我如何记录运动

  1. 当 MOUSE_MOVED 事件发生时,录制开始和结束于 MOUSE_pressed

(必须将 Main.recordMoves 设置为 true 才能发生上述情况,我使用扫描仪系统输入将其设置为 true/false。)

  1. 只要发生 MOUSE_MOVED 事件,mouseMoved 方法就会调用 MovesRecorder.record(MouseEvent e) 方法

  2. mousepressed 方法将 Main.recordMoves 布尔值设置为 false 并将记录添加到记录列表中。

鼠标.java:

public class Mouse implements MouseListener,MouseMotionListener {

    private Point location = new Point(0,0);
        
    private boolean mouSEOnScreen = false;

    private Component c;

    public Mouse(Component c) {
        this.c = c;
    }

    public void pushStraight(int x,int y) {
        if(!mouSEOnScreen) {
            c.dispatchEvent(new MouseEvent(c,MouseEvent.MOUSE_ENTERED,System.currentTimeMillis(),x,y,false));
            mouSEOnScreen = true;
        }
        c.dispatchEvent(new MouseEvent(c,MouseEvent.MOUSE_MOVED,false));
        location.setLocation(x,y);
    }

    @Override
    public void mouseClicked(MouseEvent e) {}

    @Override
    public void mousepressed(MouseEvent e) {
        if(Main.recordMoves) {
            Main.recordMoves = false;
            MovesRecorder.currentMove.time = System.currentTimeMillis() - MovesRecorder.startTime;
            MousePatterns.moves.add(MovesRecorder.currentMove);
            MovesRecorder.currentMove = null;
        }
        System.out.println("pressed");
    }

    @Override
    public void mouseReleased(MouseEvent e) {}

    @Override
    public void mouseEntered(MouseEvent e) {
        mouSEOnScreen = true;
    }

    @Override
    public void mouseExited(MouseEvent e) {
        mouSEOnScreen = false;
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        location.setLocation(e.getPoint());
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        location.setLocation(e.getPoint());
        if(Main.recordMoves) MovesRecorder.record(e);
    }

    public Point getLocation() {
        return location;
    }

    public boolean isMouSEOnScreen() {
        return mouSEOnScreen;
    }

    public Component getC() {
        return c;
    }
}

MouseRecorder.java:

public class MovesRecorder {

    public static Move currentMove;

    public static Point lastPos; //First lastPos (startingPos) is set here by Main.java

    public static long startTime;

    public static void record(MouseEvent e) {
        if(currentMove == null) {
            currentMove = new Move(Screen.mouse);
            startTime = System.currentTimeMillis();
        }
        currentMove.movements.add(new Point(e.getPoint().x - lastPos.x,e.getPoint().y - lastPos.y));
        lastPos = e.getPoint();
    }
}

移动.java:

public class Move {

    public List<Point> movements = new ArrayList<>();

    public long time;

    private Mouse m;

    public Move(Mouse m) {
        this.m = m;
    }

    public void executeEvents(int x,int y) { //This method as of Now doesn't target the params.. it just does the recording
        for(Point p : movements) {
            execute(m.getLocation().x+p.x,m.getLocation().y+p.y,MouseEvent.MOUSE_MOVED);
            try {
                Thread.sleep(time / movements.size());
            } catch (InterruptedException e) {
                e.printstacktrace();
            }
        }
    }

    private void execute(int x,int y,int event) {
        m.getC().dispatchEvent(new MouseEvent(m.getC(),event,false));
    }

}

Main.java 包含一个循环和一个 Scanner 的 switch 语句来接受命令:

while(true) {
    switch (s.next()) {
        case "movesRec":
            Main.recordMoves = true;
            MovesRecorder.lastPos = Screen.mouse.getLocation();
            break;
        case "move":
            MousePatterns.moves.get(0).executeEvents(100,100);
            break;
    }
}

MousePatterns.java 包含一个静态列表,用于添加移动:

public static List<Move> moves = new ArrayList<>();

非常感谢您的帮助!

编辑:

录音示例:https://pastebin.pl/view/e461d2bd 我希望它从 X: 274 Y: 265 开始并在 X: 100,Y: 100 结束

解决方法

考虑以下场景,在您记录的运动中,(x1,y1) 是起点,(x2,y2) 是终点,您记录的这两个点之间的唯一点是 (xm1,ym1)。

当然,在实际场景中,(x1,y1) 和 (x2,y2) 之间会有更多点,但为简单起见,我们假设只有一个点。

x1: 0,y1: 0

xm1: 45:,ym1:60

x2:100,y2:100

现在您有一个起点 (x3,y3) 并且想要按照您之前记录的相同移动行进到 (x4,y4)。为此,您需要找到 (xm2,ym2)。

x3:15,y3:45

xm2:?,ym2:?

x4:150,y4:200

考虑到 xp1 是 xm1 所经过的 x1 和 x2 之间距离的百分比,您可以执行以下操作来找到 xm2 和 ym2:

xp1 = xm1 * 100 / (x2 - x1)

xm2 = xp1 * (x4 - x3) / 100

yp1 = ym1 * 100 / (y2 - y1)

ym2 = yp1 * (y4 - y3) / 100

(在 (x1,y1) 到 (x2,y2) 场景中,xp1 = 45% 和 yp1 = 60% 因为它们已经从 (x1,y1) 和( x2,y2))

求解方程:

xp1 = 45 * 100 / 100 = 45

xm1 = 45 * 135 / 100 = 60.75

yp1 = 60 * 100 / (100 - 0) = 60

ym2 = 60 * (200 - 45) / 100 = 93

现在您只需对从 (x1,y2) 记录的每个点执行此操作,并且您将拥有从 (x3,y3) 到 (x4,y4) 的所有点>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。