2010-10-25 31 views
4

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

Я ищу способ, подобный следующему:

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

ответ

7

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

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

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

Другой способ сделать это было бы использовать Bresenhams algorithm для расчета всех точек курсор будет перемещаться через и затем петлю через каждую точку и применить его к курсору снова используя тему .Sleep, чтобы сохранить правильность времени.

Стив

+0

-1 сурова для меня, но "Cursor.Position.X + = vector.X" и "Cursor.Position.Y + = vector.Y" не будет работать. – Bolu

+0

Извините, вы правы. Я изменил его. –

+0

Работает как очарование! Благодаря! – Entity

Смежные вопросы