java 模拟人类鼠标移动的Java Robot类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12131427/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Robot class simulating human mouse movement
提问by Shawn Lien
I am working on a project about remote control, send conrdinate x and y of cursor from client to server.
我正在做一个关于远程控制的项目,将光标的 x 和 y 从客户端发送到服务器。
But
但
robot.mouseMove(x,y);
will only move the cursor to the particular point without moving the cursor form origional point
只会将光标移动到特定点而不移动光标形成原点
I have find this simple algorthim to simulate the continuing movement of mouse
我找到了这个简单的算法来模拟鼠标的持续移动
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);
}
But this algorthim still too simple, it just move from one point to other point slowly, which still unlike human behave.
但是这个算法还是太简单了,它只是从一个点缓慢移动到另一个点,这仍然不像人类的行为。
I have read some open soruce code about remote control from web, and I find this project http://code.google.com/p/java-remote-control/is using the method call MosueMovement from MouseListener class, which they use to perform the "dragging".
我已经阅读了一些关于网络远程控制的开源代码,我发现这个项目 http://code.google.com/p/java-remote-control/正在使用 MouseListener 类中的方法调用 MosueMovement,他们用来执行“拖动”。
I like to know is any one know the better way of doing this?
我想知道有人知道这样做的更好方法吗?
回答by Joey
There are a few things to consider if you want to make the artificial movement natural, I think:
如果你想让人工动作自然,我认为有几件事需要考虑:
- Human mouse movement is usually in a slight arc because the mouse hand pivots around the wrist. Also that arc is more pronounced for horizontal movements than vertical.
- Humans tend to go in the general direction, often overshoot the target and then go back to the actual target.
- Initial speed towards the target is quite fast (hence the aforementioned overshoot) and then a bit slower for precise targeting. However, if the cursor is close to the target initially the quick move towards it doesn't happen (and neither does the overshoot).
- 人类鼠标移动通常呈轻微的弧线,因为鼠标手围绕手腕旋转。此外,该弧对于水平运动比垂直运动更明显。
- 人类倾向于朝着大致的方向前进,经常超出目标,然后又回到实际目标。
- 朝向目标的初始速度非常快(因此出现上述超调),然后对于精确瞄准会慢一点。但是,如果光标最初靠近目标,则不会发生快速移动(也不会发生过冲)。
This is a bit complex to formulate in algorithms, though.
但是,这在算法中制定有点复杂。
回答by davidbuzatto
Take a look in this example that I wrote. You can improve this to simulate what Joey said. I wrote it very fast and there are lots of things that can be improved (algorithm and class design). Note that I only deal with left to right movements.
看看我写的这个例子。您可以改进它以模拟乔伊所说的话。我写得非常快,还有很多可以改进的地方(算法和类设计)。请注意,我只处理从左到右的运动。
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();
}
}
}
}
}
回答by Joonas Vali
For anyone in the future: I developed a library for Java, that mimics human mouse movement. The noise/jaggedness in movement, sinusoidal arcs, overshooting the position a bit, etc. Plus the library is written with extension and configuration possibilities in mind, so anyone can fine tune it, if the default solution is not matching the case. Available from Maven Central now.
对于未来的任何人:我为 Java 开发了一个库,它模仿人类鼠标的运动。运动中的噪声/锯齿、正弦弧、位置有点过冲等。此外,库的编写考虑了扩展和配置的可能性,因此如果默认解决方案与情况不匹配,任何人都可以对其进行微调。现在可从 Maven 中心获得。