C# 平滑物体移动

4

我已经有了通过C#代码移动和点击鼠标所需的所有代码,但我不想仅将鼠标位置设置为XY,那样看起来很生硬。相反,我希望在Z秒内从点X1,Y1到点X2,Y2实现平滑过渡。类似于关键帧技术。

我正在寻找类似于以下方法:

public void TransitionMouse(int x, int y, double durationInSecs)

该函数将平稳地将鼠标从当前位置移动到 xy,在 durationInSecs 秒内完成。该函数称为:

public void MoveMouse(int x, int y)

这将立即移动鼠标到 xy


编辑

感谢各位的帮助!以下是完成且经过测试的代码:

    [DllImport("user32.dll")]
    static extern bool SetCursorPos(int X, int Y);

    public void TransitionMouseTo(double x, double y, double durationSecs)
    {
        double frames = durationSecs*100;

        PointF vector = new PointF();
        PointF mousePos = Cursor.Position;

        vector.X = (float)((x - mousePos.X) / frames);
        vector.Y = (float)((y - mousePos.Y) / frames);

        for (int i = 0; i < frames; i++)
        {
            SetCursorPos((int)(mousePos.X += vector.X), (int)(mousePos.Y += vector.Y));
            Thread.Sleep((int)((durationSecs / frames) * 1000.0));
        }
    }
2个回答

7

有几种方法可以实现这个目标。其中一种选择是计算每一帧需要移动鼠标的向量,并在时间段内应用它到鼠标位置。

所以,如果我们在位置 5,5 并且想要在 10 帧内移动到 20,30,则我们的向量如下:

val = (target - start) / frames;

x = (20 - 5) / 10; y = (30 - 5) / 10;

向量为 1.5,2.5

然后,在您的 TransitionMouse 方法中,使用 Thread.Sleep 方法来控制速度,慢慢地将向量应用于鼠标位置,直到达到您希望的持续时间。代码可能如下所示:

public void TransitionMouseTo(int x, int y, int durationSecs)
{
    int frames = 10;

    PointF vector = new PointF();

    vector.X = (x - Cursor.Position.X) / frames;
    vector.Y = (y - Cursor.Position.Y) / frames;  

    for (int i = 0; i < frames; i++)
    {
        Point pos = Cursor.Position;

        pos.X += vector.X;
        pos.Y += vector.Y;

        Cursor.Position = pos;

        Thread.Sleep((durationSecs / frames) * 1000);
    }
}

另一种做法是使用Bresenham算法计算鼠标光标将经过的所有点,然后循环遍历每个点并再次应用到光标上,使用Thread.Sleep保持时间正确。
Steve

-1 对我来说太严厉了,但是“Cursor.Position.X += vector.X”和“Cursor.Position.Y += vector.Y”不起作用。 - Bolu
我想补充一下,你不能设置Cursor.Position,必须使用Win32函数SetCursorPos。但是更改后,它可以工作! :D - Entity
好的,我以为你可以,但是你明白我的意思:)。我必须承认在发布代码之前我没有测试过它。 - Steve Whitfield
@TheAdamGaskins,您能发一下TransitionMouseTo函数的可用代码吗? - Bolu
@TheAdamGaskins,感谢你的代码。我认为你可以使用Cursor.Position = new Point((int)(mousePos.X += vector.X), (int)(mousePos.Y += vector.Y)) 来替换SetCursorPos这行代码。 - Bolu

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接