You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#使用mouse_event实现鼠标相对位移时如何避免瞬移实现平滑移动?

要实现相对位移下的鼠标平滑移动,同时解决像素取整的精度损失问题,核心思路是累计小数误差,再结合时间分片实现平滑过渡,具体实现如下:

完整实现代码

using System.Runtime.InteropServices;
using System.Threading;
using System;

public class MouseController
{
    [DllImport("user32.dll")]
    static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
    private const int MOUSEEVENTF_MOVE = 0x0001;
    // 单步间隔,单位毫秒,10ms对应100fps,16ms对应60fps,可根据流畅度需求调整
    private const int StepInterval = 10;

    public void MoveMouse(int xDelta, int yDelta, double timeInMilliseconds)
    {
        // 时长过短或无位移直接移动,无需拆分
        if (timeInMilliseconds <= StepInterval || (xDelta == 0 && yDelta == 0))
        {
            mouse_event(MOUSEEVENTF_MOVE, xDelta, yDelta, 0, 0);
            return;
        }

        // 计算总步数
        int totalSteps = (int)Math.Round(timeInMilliseconds / StepInterval);
        // 单步理想位移(带小数)
        double stepX = (double)xDelta / totalSteps;
        double stepY = (double)yDelta / totalSteps;
        // 累计误差变量
        double accumX = 0.0;
        double accumY = 0.0;

        for (int i = 0; i < totalSteps; i++)
        {
            accumX += stepX;
            accumY += stepY;
            // 取当前累计的整数部分作为实际移动量
            int moveX = (int)Math.Round(accumX);
            int moveY = (int)Math.Round(accumY);
            // 减去已经移动的整数部分,剩余小数留到下一次累计
            accumX -= moveX;
            accumY -= moveY;
            // 执行移动
            mouse_event(MOUSEEVENTF_MOVE, moveX, moveY, 0, 0);
            // 等待单步间隔
            Thread.Sleep(StepInterval);
        }

        // 最后补充剩余的误差(极端情况才会用到,保证最终位移完全准确)
        if (Math.Round(accumX) != 0 || Math.Round(accumY) != 0)
        {
            mouse_event(MOUSEEVENTF_MOVE, (int)Math.Round(accumX), (int)Math.Round(accumY), 0, 0);
        }
    }

    // 原有直接移动的方法可保留
    public static void MoveMouseDirect(int xDelta, int yDelta)
    {
        mouse_event(MOUSEEVENTF_MOVE, xDelta, yDelta, 0, 0);
    }
}

实现说明

  • 误差累计机制:每一步的小数位移不会直接丢弃,而是累积到下一次计算,当累计值超过1个像素时才会实际移动对应像素,最终总位移和传入的xDelta、yDelta完全一致,不会出现精度损失。
  • 平滑度控制:可以通过调整StepInterval的值控制流畅度,数值越小帧率越高,移动越平滑,对应CPU占用也会略高,常规场景下10~16ms的间隔就可以达到人眼感知不到卡顿的效果。
  • 边界处理:对极短时长、零位移的场景做了兼容,直接一步移动避免不必要的性能消耗,最后额外补充剩余误差的逻辑保证极端场景下位移完全准确。

内容的提问来源于stack exchange,提问作者zjebinsky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 08:54:00