Простая анимация с использованием C#/Windows Forms
Мне нужно выбить быструю анимацию в C#/Windows Forms для отображения Хэллоуина. Просто несколько 2D фигур, движущихся на сплошном фоне. Поскольку это всего лишь один раз, я не хочу устанавливать и изучать для этого целый новый набор инструментов. (Наборы разработчика DirectX, Silverlight, Flash и т. Д.) Я также должен установить это на нескольких компьютерах, так что все, кроме базовых.Net Framework (2.0), будет проблемой в заднице.
Для инструментов у меня есть VS2k8, 25-летний опыт разработки, тачка, плащ Холокоста и около 2-х дней, чтобы его выбить. Я не делал анимацию с тех пор, как использовал ассемблер на своем Atari 130XE (ура для переворачивания страницы и графики игрока / ракеты!)
Совет? Вот некоторые вещи, которые я хотел бы знать:
- Я могу рисовать на любом пустом виджете (например, на панели), используя его обработчик OnPaint, верно? Вот так я бы нарисовал собственный виджет. Есть ли лучшая техника, чем эта?
- Есть ли в Windows Forms техника перелистывания страниц для такого рода вещей? Я не ищу высокую частоту кадров, просто столько мерцания / рисования, сколько необходимо.
Благодарю.
Сообщение Mortem Edit... "пару дней спустя кодирования"
Ну, проект готов. Приведенные ниже ссылки пригодились, хотя некоторые из них были 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 изнутри моего цикла таймера. Нет мерцания на всех.
2 ответа
Установите таймер на желаемую частоту кадров. При каждом срабатывании таймера внутреннее представление фигур на экране (вашей модели) в соответствии с движением анимации, которое вы хотите достичь, затем вызовите Invalidate(true)
, Внутри OnPaint просто нарисуйте модель на экране.
Ах да, и вы, вероятно, хотите включить Двойную буферизацию (это похоже на автоматическое перелистывание страниц).
Оба из них дают хорошие примеры анимации. Код довольно прост. Я использовал их, когда мне нужно было сделать быструю анимацию для моего сына.