平滑方向变化的线条,使用 java 机器人模拟来自模式的用户输入

Smoothing out lines on direction change , simulating user input from pattern with java 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}
        });

一切正常,芽,显然老鼠的运动很活泼,需要进行平滑处理,使其看起来像人类,图像:

整个鼠标移动的函数是:

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);
                        }
                    }
                }
            }
        }
    }

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

我在想的是 incrementing/decrementing next/previous 移动方向 side/up/down 的移动值 last/first [=43= 的 20% ] 增量 increasing/decreasing 这个动作萌芽整个事情会非常大 SWITCH 语句,大量的工作而且效率不高。

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

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

好的,经过大量的书面工作(是的,我把它画在纸上),我设法做到了这一点,而没有使用一些复杂的数学或样条 api 等

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

这种方法非常有效,性能提升超过了曲线中较少的细节。

它绝不是带有额外用户输入的完美芽,随机数加法与我的想法差不多。