java - 平滑方向变化的线条,使用 java Robot 模拟用户输入模式

标签 java math input robot

所以我正在创建模拟用户鼠标移动的应用程序。

我的模式格式为[步数,方向]

 pattern.put(Weapon.NAME_TEST_DOWN2, new int[][]{ //sens: 1.0 steps:5,10ms delay
            {600, DOWN},
            {100, RIGHT | DOWN},
            {400, LEFT | DOWN},
            {100, LEFT},
            {200, NONE},
            {600, RIGHT},
            {400, NONE},
            {400, LEFT}
        });

一切工作正常,显然,mouse 的运动很快,需要平滑,以便看起来像人类,图像:

enter image description here

整个鼠标移动的函数是:

private final int stepAmount = 1;
@SuppressWarnings("FieldMayBeFinal")
private int delay = (int) (2 * CsgoRr.getModel().getAppPrefs().getIngameSensitivity()); // increments of 1 1.5 2 2.5 etc
   @SuppressWarnings("CallToPrintStackTrace")
    public void reduceRecoil() {

        @SuppressWarnings("UnusedAssignment")
        int directionFlag = 0;
        int previousDirectionFlag;
        int nextDirectionFlag = RecoilPatternInfo.NONE;
        for (int row = 0; row < recoilPattern.length; row++) {

            if (weapon.isTriggerPulled()) {
                int duration = recoilPattern[row][0];
                directionFlag = recoilPattern[row][1];
                previousDirectionFlag = (row != 0) ? recoilPattern[row - 1][1] : RecoilPatternInfo.NONE;
                try {
                    nextDirectionFlag = recoilPattern[row + 1][1];
                } catch (IndexOutOfBoundsException e) {
                    e.printStackTrace();
                }
                switch (directionFlag) {
                    case (RecoilPatternInfo.DOWN): {
                        while ((duration -= delay) > 0) {
                            if (weapon.isTriggerPulled()) {
                                mouseMove(MouseInfo.getPointerInfo().getLocation().x,
                                        MouseInfo.getPointerInfo().getLocation().y + stepAmount);
                            } else {
                                return;
                            }
                            this.delay(delay);
                        }
                        break;
                    }
                    case (RecoilPatternInfo.DOWN | RecoilPatternInfo.LEFT): {
                        while ((duration -= delay) > 0) {
                            if (weapon.isTriggerPulled()) {
                                mouseMove(MouseInfo.getPointerInfo().getLocation().x - stepAmount,
                                        MouseInfo.getPointerInfo().getLocation().y + stepAmount);
                            } else {
                                return;
                            }
                            this.delay(delay);
                        }
                        break;
                    }
                    case (RecoilPatternInfo.DOWN | RecoilPatternInfo.RIGHT): {
                        while ((duration -= delay) > 0) {
                            if (weapon.isTriggerPulled()) {
                                mouseMove(MouseInfo.getPointerInfo().getLocation().x + stepAmount,
                                        MouseInfo.getPointerInfo().getLocation().y + stepAmount);
                            } else {
                                return;
                            }
                            this.delay(delay);
                        }
                        break;
                    }
                    case (RecoilPatternInfo.LEFT): {
                        while ((duration -= delay) > 0) {
                            if (weapon.isTriggerPulled()) {
                                mouseMove(MouseInfo.getPointerInfo().getLocation().x - stepAmount,
                                        MouseInfo.getPointerInfo().getLocation().y);
                            } else {
                                return;
                            }
                            this.delay(delay);
                        }
                        break;
                    }
                    case (RecoilPatternInfo.RIGHT): {
                        while ((duration -= delay) > 0) {
                            if (weapon.isTriggerPulled()) {
                                mouseMove(MouseInfo.getPointerInfo().getLocation().x + stepAmount,
                                        MouseInfo.getPointerInfo().getLocation().y);
                            } else {
                                return;
                            }
                            this.delay(delay);
                        }
                        break;
                    }

                    case (RecoilPatternInfo.UP): {
                        while ((duration -= delay) > 0) {
                            if (weapon.isTriggerPulled()) {
                                mouseMove(MouseInfo.getPointerInfo().getLocation().x,
                                        MouseInfo.getPointerInfo().getLocation().y - stepAmount);
                            } else {
                                return;
                            }
                            this.delay(delay);
                        }
                        break;
                    }
                    case (RecoilPatternInfo.UP | RecoilPatternInfo.LEFT): {
                        while ((duration -= delay) > 0) {
                            if (weapon.isTriggerPulled()) {
                                mouseMove(MouseInfo.getPointerInfo().getLocation().x - stepAmount,
                                        MouseInfo.getPointerInfo().getLocation().y - stepAmount);
                            } else {
                                return;
                            }
                            this.delay(delay);
                        }
                        break;
                    }
                    case (RecoilPatternInfo.UP | RecoilPatternInfo.RIGHT): {
                        while ((duration -= delay) > 0) {
                            if (weapon.isTriggerPulled()) {
                                mouseMove(MouseInfo.getPointerInfo().getLocation().x + stepAmount,
                                        MouseInfo.getPointerInfo().getLocation().y - stepAmount);
                            } else {
                                return;
                            }
                            this.delay(delay);
                        }
                        break;
                    }
                    default: {//RecoilPatternInfo.NONE
                        while ((duration -= delay) > 0) {
                            if (weapon.isTriggerPulled()) {
                                mouseMove(MouseInfo.getPointerInfo().getLocation().x,
                                        MouseInfo.getPointerInfo().getLocation().y);
                            } else {
                                return;
                            }
                            this.delay(delay);
                        }
                    }
                }
            }
        }
    }

因为我知道下一步要朝哪个方向移动,并且我知道在方向改变之前还剩下多少步,所以我应该能够做到这一点。

我的想法是增加/减少下一个/上一个移动方向的侧/上/下移动值,仅在最后/前 20% 的步骤中。然后增量增加/减少这个移动芽整个事情将是一个非常大的 SWITCH 语句,大量工作而且效率低下。

有更好的方法吗?或者我会被迫接受我的第一个想法?

对于最有效的工作解决方案有什么想法吗?

最佳答案

好吧,经过大量的文书工作(是的,我把它画在纸上),我成功地做到了这一点,而无需使用一些复杂的数学或样条 API 等。

我所做的是遵循我的第一个想法,考虑到下一个方向并缓慢预转,使用基于到目前为止已完成的图案和步骤的百分比的平滑因子的偏差。

这种方法确实有效,性能提升胜过曲线中较少的细节。

它绝不是带有额外用户输入的完美花蕾,随机数添加几乎就是我的想法。

关于java - 平滑方向变化的线条,使用 java Robot 模拟用户输入模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38897143/

相关文章:

java - 如何命名Java变量 "public"

java - 如何在 Java 中创建一个随机的 BigDecimal?

javascript - 如何检查是否设置了位(没有按位运算)?

java - Android 多点触控 - TouchMove 事件中的 IllegalArgumentException

java - 如何组织项目?

java - servlet/grails 如何正确地将 mp4 文件提供给 Safari?

java - 带字符串且无参数的方法

iphone - 正方形和矩形像素坐标之间的转换

C++多行输入

css - 仅删除搜索字段周围的边框