Классика задач связанной с анимацией. Требуется так перерисовать картинку, чтобы пользователь не видел мерцания, связанного с очисткой объекта canvas.
Почему возникает эффект мерцания при перерисовке?
Обычно это связано с техникой создания следующего кадра. Он рисуется как бы с нуля, всё объекты стираются, картинка заливается фоном, и начинается прорисовка объектов согласно последним изменениям сцены.
Двойная буферизация
Для того чтобы избежать данного эффекта — используют буферизацию. Новый кадр создаётся в памяти, а потом копируется на canvas, полностью подготовленный к показу. Пользователь не видит мерцания, вызванного полной очисткой кадра перед перерисовкой.
Пример реализации двойной буферизации в C#
Рассмотрим метод ReDraw, который обновляет (рендерит и выводит) нарисованное изображение. Изображение состоит из массива эллипсов, которые движутся по некоторому алгоритму, который в данной статье не важен.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
public partial class Form1 : Form ... private void ReDraw() { // создание буфера для нового кадра Bitmap Image = new Bitmap(Width, Height); Graphics g = Graphics.FromImage(Image); // заливка черным цветом (создание фона) g.FillRectangle(Brushes.Black, 0, 0, Width, Height); // рисуем эллипсы для объектов из глобального массива // тут должна идти ваша графика foreach (var item in starField.Stars) { float r = Math.Min(3, item.r); g.FillEllipse(Brushes.White, new RectangleF(item.plainX * Width, item.plainY * Height, r, r)); } // теперь нужно скопировать кадр на канвас формы var FormG = CreateGraphics(); FormG.DrawImageUnscaled(Image, 0, 0); // освобождаем задействованные в операции ресурсы g.Dispose(); Image.Dispose(); FormG.Dispose(); } ... } |
В качестве буфера мы используем объект Bitmap. В месте, где выполняется вывод эллипсов и заливка — вы можете подставить ваш код.