C#平滑对象移动

C#平滑对象移动,c#,transition,smooth,keyframe,C#,Transition,Smooth,Keyframe,我有通过C#code移动和单击鼠标所需的所有代码,但我不想只将鼠标位置设置为X和Y;那看起来很不自然。相反,我希望在Z秒内从点X1,Y1平滑过渡到点X2,Y2。类似于关键帧 我正在寻找一种类似的方法: public void TransitionMouse(int x, int y, double durationInSecs) 它只需在durationInSecs秒内将鼠标从当前位置平滑移动到x和y。我有一个函数叫做: public void MoveMouse(int x, int y)

我有通过C#code移动和单击鼠标所需的所有代码,但我不想只将鼠标位置设置为
X
Y
;那看起来很不自然。相反,我希望在Z秒内从点
X1,Y1
平滑过渡到点
X2,Y2
。类似于关键帧

我正在寻找一种类似的方法:

public void TransitionMouse(int x, int y, double durationInSecs)
它只需在
durationInSecs
秒内将鼠标从当前位置平滑移动到
x
y
。我有一个函数叫做:

public void MoveMouse(int x, int y)
将鼠标立即移动到
x
y


编辑

谢谢你们的帮助!以下是完成并经过测试的代码:

    [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));
        }
    }
[DllImport(“user32.dll”)]
静态外部bool SetCursorPos(intx,inty);
公共无效转换MouseTo(双x、双y、双持续时间秒)
{
双帧=持续时间秒*100;
PointF向量=新的PointF();
鼠标点=光标位置;
vector.X=(float)((X-mousePos.X)/frames);
vector.Y=(float)((Y-mousePos.Y)/frames);
对于(int i=0;i
实际上取决于平滑的定义,但是大多数“平滑”运动算法使用样条曲线在2个或更多数据点之间插值

这可能会有所帮助

您可以通过几种方式来实现这一点。一个选项是计算每帧移动鼠标所需的向量,并在时间段内将其应用于鼠标位置

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

val=(目标-开始)/帧

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);
    }
}
public void TransitionMouseTo(int x、int y、int durationSecs)
{
int帧=10;
PointF向量=新的PointF();
vector.X=(X-Cursor.Position.X)/frames;
vector.Y=(Y-Cursor.Position.Y)/frames;
对于(int i=0;i
另一种方法是使用Thread.Sleep计算鼠标光标将要移动的所有点,然后循环通过每个点,并再次将其应用于光标,以保持计时正确


Steve

-1对我来说很苛刻,但是“Cursor.Position.X+=vector.X”和“Cursor.Position.Y+=vector.Y”不起作用。我可以补充一点,您不能设置Cursor.Position,您必须使用Win32函数SetCursorPos。但在改变了这一点之后,它就起作用了!:杜克,我以为你可以,但你明白了:)。我必须承认我在发布之前没有测试代码。@TheAdamGaskins,你能发布你的TransitionMouseTo函数的工作代码吗?@TheAdamGaskins,谢谢你的代码。我认为您可以使用Cursor.Position=newpoint((int)(mousePos.X+=vector.X),(int)(mousePos.Y+=vector.Y))来替换SetCursorPos行。