Как плавно анимировать расположение Windows Forms с разными скоростями? - PullRequest
0 голосов
/ 09 июня 2009

Я пытался плавно анимировать некоторые местоположения Windows Form, но у меня возникают некоторые проблемы, если я хочу, чтобы скорость была переменной. Другими словами, если я хочу разрешить пользователю выбирать предпочтительную скорость для анимации.

Я нашел следующую статью, которая очень помогла мне выполнить анимацию, которую я искал, для моей формы. Кажется, это лучше во всех отношениях, чем подход BackgroundWorker или Threads, который я пробовал в прошлом: http://www.vcskicks.com/animated-windows-form.html

Моя единственная проблема сейчас - поддерживать плавную анимацию, если я хочу иметь разные скорости анимации. В моем коде важны два значения: FPS и PX . FPS представляет количество кадров в секунду (что еще), а PX представляет количество пикселей для перемещения формы.

Задача 1) Чтобы получить максимально плавную анимацию, я бы предпочел, чтобы форма перемещалась на 1 пиксель за раз, но я не думаю, что смогу перемещать форму так же быстро, как я. хочу так. Увеличение значения FPS до очень высокого значения, похоже, не дает никакого эффекта, как будто есть предел, и выше этого предела не будет видимых различий. Я уверен, что есть хорошее объяснение этому.

Мой вопрос здесь: у вас есть какое-нибудь хорошее решение для этой проблемы или единственное решение - изменить значение PX и переместить форму более чем на 1 пиксель, если я хочу более быстрое движение?

Задача 2) Если решение вышеуказанного вопроса заключается в соответствующем изменении значения PX, я обнаружил (путем тестирования различных значений), что значение FPS, равное 300, будет достаточным для моих потребностей в перемещении формировать так медленно и так быстро, как я хочу. Затем, если мне нужно 10 скоростей, перемещение формы на 1, 2, 3, 4, 5, 6, 7, 8, 9 и 10 пикселей обеспечивает медленную и быструю плавную анимацию, как я и хочу. Если бы я хотел 5 скоростей, я мог бы использовать, например, 2, 4, 6, 8, 10.

Мой вопрос здесь такой: есть ли проблема в использовании значения, такого как 300, для FPS? Есть ли плохие последствия для такой стоимости?

А вот мой текущий код:

public partial class Form1 : Form {

    bool dir = true;

    public Form1() {
        InitializeComponent();

        Location = new Point(1280/2 - Width, 800/2 - Height/2);
    }

    private void button1_Click(object sender, EventArgs e) {
        double FPS = 300;
        int PX = 1;
        long lastTicks = 0;
        long currentTicks = 0;
        double interval = (double)Stopwatch.Frequency / FPS;

        while(dir ? Left <= 1280/2 : Left >= 1280/2 - Width) {
            Application.DoEvents();

            currentTicks = Stopwatch.GetTimestamp();

            if(currentTicks >= lastTicks + interval) {
                lastTicks = Stopwatch.GetTimestamp();

                this.Location = new Point(dir ? Left + PX : Left - PX, Top);

                this.Invalidate(); //refreshes the form
            }

            Thread.Sleep(1); //frees up the cpu
        }

        dir = !dir;
    }

}

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

Ответы [ 4 ]

4 голосов
/ 11 июня 2009

Попробуйте эту реализацию моего предыдущего предложения (без учета FPS):

public partial class Form1 : Form
{
    private bool go;
    private int dx = 1;
    public Form1()
    {
        InitializeComponent();
    }
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        if (go)
        {
            this.Location = new Point(this.Location.X + dx, this.Location.Y);
            if (Location.X < 10 || Location.X > 1200)
            {
                go = false;
                dx = -dx;
            }
            else
            {
                this.Invalidate();
            }
        }
    }
    private void button1_Click(object sender, EventArgs e)
    {
        go = true;
        this.Invalidate();
    }
}

Я думаю, вам, вероятно, придется выходить за пределы winforms, чтобы получить более высокий FPS.

1 голос
/ 09 июня 2009

Я думаю, что Windows ограничивает скорость перерисовки, поэтому не будет иметь значения, если вы увеличите FPS до безумных значений; если вы хотите увидеть более высокую частоту кадров, вам, вероятно, придется получить что-то вроде анимации XNA / DirectX.

Вы можете использовать Таймер и написать обработчик прошедшего события, который будет перемещать и аннулировать вашу форму. Для этого вам не придется выполнять Thread.Sleep или бухгалтерский учет с последними тиками и интервальными расчетами, и это будет происходить с регулярной каденцией. Кроме того, вместо условного кода вокруг логического значения 'dir', вы можете отрицать значение PX, когда хотите изменить направление (и делать только дополнения вместо тернарного оператора в dir); это возможно, поскольку вычитание - это то же самое, что добавление отрицания.

Это должно облегчить расширение вашей анимации для выполнения других задач. Для развлечения вы также можете создать PY для вертикального перемещения. В любом случае, я надеюсь, вам понравится. :)

0 голосов
/ 11 июня 2009

Если вы получили желаемый результат со значением FPS 300, я бы согласился. Концепция Frames Per Second для WinForms не похожа на видеоигры с интенсивной графикой, поэтому высокое значение не будет проблемой. Здесь значение FPS просто регулирует частоту выполнения кода.

0 голосов
/ 11 июня 2009

Super Over-Kill Solution

Резюме: делает анимацию движения вашего окна и воспроизводит его (возможно, в полноэкранном режиме)

подробности:
Предположим, ваше окно имеет размер 100x100 и @ 0,0
Сделайте снимок экрана, ну, экрана: (0,0) - (200 200).
Используйте снимок экрана, чтобы создать клип, который изображает перемещение вашего окна от 0,0 до 100,100
Затем создайте окно без рамки (0,0) - (200,200), поместите на него видеоплеер и воспроизведите анимацию движения вашего окна внутри.

Излишне говорить, что ваше окно будет статичным. Но вы можете получить лучшую анимацию. Вы даже можете добавить некоторые эффекты к движению вашего окна, например, пули в матрице или корабли Necromunga.

...