Простая анимация с использованием C# / Windows Forms

Мне нужно выбить быструю анимацию в C# / Windows Forms для отображения Хэллоуина. Просто несколько 2D-фигур, движущихся по сплошному фону. Поскольку это всего лишь быстрый разовый проект, я В самом деле не хочу устанавливать и изучать для этого целый новый набор инструментов. (Наборы для разработчиков DirectX, Silverlight, Flash и т. д.). Я также должен установить это на несколько компьютеров, чтобы все, что выходит за рамки базовой .Net framework (2.0), было бы головной болью.

Что касается инструментов, у меня есть VS2k8, 25 лет опыта разработки, тачка, маскировка холокоста и около 2 дней, чтобы разобраться с этим. Я не делал анимацию с тех пор, как использовал ассемблер на моем Atari 130XE (ура для перелистывания страниц и графики игрока / ракеты!)

Совет? Вот что я хотел бы знать:

  • Я могу рисовать на любом пустом виджете (например, на панели), возясь с его обработчиком OnPaint, верно? Вот так я бы нарисовал кастомный виджет. Есть ли лучшая техника, чем эта?
  • Есть ли в Windows Forms техника перелистывания страниц для подобных вещей? Я не стремлюсь к высокой частоте кадров, просто к минимуму мерцания / рисования, если это необходимо.

Спасибо.

Посмертное редактирование ... "через пару дней кодирования"

Что ж, проект готов. Приведенные ниже ссылки пригодились, хотя некоторые из них были 404. (я бы хотел, чтобы SO позволил пометить более одного ответа как «правильный»). Самой большой проблемой, которую мне пришлось преодолеть, было мерцание и постоянная ошибка, когда я пытался рисовать прямо в форме.

  • Использование события OnPaint для формы: плохая идея. У меня никогда не получалось, чтобы это работало; множество загадочных ошибок (переполнение стека или исключение ArgumentNullExceptions). Я закончил использовать панель размером для заполнения формы, и это сработало.
  • В любом случае использование метода OnPaint выполняется медленно. Где-то в Интернете я прочитал, что создание PaintEventArgs было медленным, и они не шутили. Когда я отказался от этого, исчезло много мерцания. Пропустите OnPaint / Invalidate () и просто раскрасьте его самостоятельно.
  • Установка всех параметров «двойной буферизации» в форме по-прежнему оставляла некоторое мерцание, которое необходимо было исправить. (И я нашел противоречивые документы, в которых говорилось «установить их в элементе управления» и «установить их в форме». У элементов управления нет метода .SetStyle ().) Я не тестировал без них, поэтому они могут быть что-то делать (this - это форма):

        this.SetStyle(ControlStyles.UserPaint, true);
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
    

Итак, рабочая лошадка кода выглядела так (pf - это панель управления):

    void PaintPlayField()
    {
        Bitmap bufl = new Bitmap(pf.Width, pf.Height);
        using (Graphics g = Graphics.FromImage(bufl))
        {
            g.FillRectangle(Brushes.Black, new Rectangle(0, 0, pf.Width, pf.Height));
            DrawItems(g);
            DrawMoreItems(g);
            pf.CreateGraphics().DrawImageUnscaled(bufl, 0, 0);
        }
    }

И я только что вызвал PaintPlayField изнутри цикла таймера. Никакого мерцания.

см. соответствующий вопрос простой анимации в winforms.

user18443 12.10.2008 11:18

В идеале вы должны повторно использовать Bitmap в своем коде в каждом кадре, если ширина и высота не меняются. Распределять его каждый кадр расточительно. Он также должен быть удален по завершении, как и возвращаемое значение pf.CreateGraphics().

Drew Noakes 02.05.2017 14:14
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
58
2
85 725
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Установите таймер с желаемой частотой кадров. При каждом срабатывании таймера вращайте внутреннее представление фигур на экране (вашу модель) в соответствии с движением анимации, которое вы хотите достичь, затем вызывайте Invalidate(true). Внутри OnPaint просто нарисуйте модель на экране.

Ах да, и вы, вероятно, захотите включить двойную буферизацию (это похоже на автоматическое перелистывание страниц).

2d Game Primer

Анимация на основе таймера

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

Другие вопросы по теме