C # плавное движение объекта - PullRequest
4 голосов
/ 25 октября 2010

У меня есть весь необходимый код для перемещения и щелчка мышью с помощью кода C #, но я не хочу просто устанавливать положение мыши на X и Y;это будет выглядеть вяло.Вместо этого я хочу плавно перейти от точки X1, Y1 к точке X2, Y2 в течение Z секунд.Похож на ключевой кадр.

Я ищу метод, похожий на этот:

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

Он просто плавно переместит мышь из текущей позиции в x и y вdurationInSecs секунд.У меня есть функция с именем:

public void MoveMouse(int x, int y)

, которая перемещает мышь к x, y немедленно.


EDIT

Спасибо за помощь, ребята!Вот готовый и проверенный код:

    [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 голосов
/ 25 октября 2010

Вы можете сделать это несколькими способами.Один из вариантов - вычислить вектор, необходимый для перемещения мыши в каждом кадре, и применить его в течение периода времени к позиции мыши.

Итак, если мы находимся в позиции 5,5 и хотим перейти к 20,30 на 10 кадров, наш вектор будет следующим:

val = (target - start) / frames;

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

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

Еще один способ сделать это - использовать алгоритм Брезенхамса , чтобы вычислить все точки, через которые будет перемещаться курсор мыши, и затем проходить через каждую точкуи примените его к курсору снова, используя Thread.Sleep, чтобы сохранить правильное время.

Стив

0 голосов
/ 25 октября 2010

действительно зависит от вашего определения сглаживания, однако в большинстве алгоритмов «плавного» движения используется сплайн для интерполяции между 2 или более точками данных.

это может помочь http://geekswithblogs.net/JuanDoNeblo/archive/2007/10/25/Data-Interpolation-with-SPLINE-in-Csharp.aspx

...