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

hfyxw5xn  于 2021-06-26  发布在  Java
关注(0)|答案(1)|浏览(346)

我创建了一个有趣的小项目,目标是记录我做出的自然鼠标动作,然后回放,但要朝向目标。
问:假设我制作并记录一个自然运动,结束于x:250,y:278,现在我想要的是让自然运动记录结束于我指定的目标坐标(ex:x:100,y:100)。
现在来看代码:(请注意,代码并不干净,但如果我可以这么说的话,它只是第一个原型,所以请在阅读时记住这一点)。
我如何记录动作:
当鼠标移动事件发生时,录制从按下鼠标开始到结束。
(main.recordmoves必须设置为true才能执行上述操作,我使用scanner系统输入将其设置为true/false。)
每当发生mouse\u moved事件时,mousemoved方法调用movesrecorder.record(mouseevent e)方法。
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(),0,x,y,
                    0,false));
            mouseOnScreen = true;
        }
        c.dispatchEvent(new MouseEvent(c,MouseEvent.MOUSE_MOVED,System.currentTimeMillis(),0,x,y,
                0,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();
    }
}

move.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,
                System.currentTimeMillis(),0,
                x,y,0,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<>();

非常感谢您的帮助!

zvms9eto

zvms9eto1#

考虑下面的场景,在你记录的一个动作中(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=xm1100/(x2-x1)
xm2=xp1
(x4-x3)/100
yp1=ym1100/(y2-y1)
ym2=yp1
(y4-y3)/100
(在(x1,y1)到(x2,y2)场景中,xp1=45%,yp1=60%,因为它们从(x1,y1)和(x2,y2)之间的距离“行驶”了45%和65%)
求解方程:
xp1=45100/100=45
xm1=45
135/100=60.75
yp1=60100/(100-0)=60
ym2=60
(200-45)/100=93
现在您只需对从(x1,y1)到(x2,y2)记录的每个点执行此操作,您将拥有从(x3,y3)到(x4,y4)的所有点

相关问题