Спрайтовая анимация

Цель примера — показать способ рисования спрайтов в динамике. Спрайт (англ. Sprite — фея; эльф) — графический объект в компьютерной графике, чаще всего — растровое изображение, которое можно отобразить на экране.

Предварительные действия. Создадим в Paint три изображения на белом фоне, каждый размером 100х100 пикселей. Нарисуем (без рамок) в первом квадрате красный круг, во втором — зеленый, третий квадрат оставим белым. Сохраним их в формате JPEG, присвоив имена файлов spr1.jpg, spr2.jpg, spr3.jpg соответственно.

spr123

Будем изображать перемещение шара по некоторой траектории (например, по прямой) на холсте графического объекта pictureBox1, который мы поместим на форму.   Часто бывает удобно использовать такого рода контейнеры вместо непосредственного рисования на форме. Для хранения трех спрайтов будем использовать невизуальный компонент ImageList1 (список изображений), для управления анимацией будем использовать компонент timer1. Создадим приложение Windows Form и зададим имя namespace = Sprite.

СпрайтФормаНа вкладке Form1.cs (Конструктор) мы видим  pictureBox1 (в пунктирной рамке), а также невизуальные компоненты timer1 и  ImageList1. Пусть pictureBox1 занимает не все окно формы.  В коллекцию изображений (свойство  imageList1.Images) добавим через окно Свойства наши три рисунка с индексами 0,1,2. Для таймера свойству timer1.Interval присвоим 100. Это будет означать, что изменение  положения спрайта-шарика будет происходить примерно 14 раз в секунду. Создадим заготовку обработчика события timer1.Tick — метод :
private void timer1_Tick(object sender, EventArgs e)
Тогда первоначальный код проекта (Form1.cs) будет выглядеть так:

using System;
using System.Drawing;
using System.Windows.Forms;
namespace Sprite
{
    public partial class Form1 : Form
    {
       public Form1()
       {
          InitializeComponent();
       }
       private void timer1_Tick(object sender, EventArgs e)
       {
       }
    }
}

Примечание. Отметим, что при генерации шаблона Windows-приложения добавляются в раздел using  библиотеки, которые нам будут не нужны. Нажав в окне редактора кода Form1.cs правую кнопку, выберем из меню позицию «Управление директивами using», а в ней выберем «Удалить неиспользуемые директивы using», после чего ненужные нам директивы будут удалены.

У нас все готово для программирования спрайтов. В описание класса Form1 перед конструктором  Form1() введем описание двух объектов:
Graphics g;     //  графический объект — некий холст
Bitmap buf;     //  буфер для Bitmap-изображения
и трех переменных класса:
int stage = 0;      // индекс чередующегося шара (красный — 0, зеленый — 1, белый — 2)
int x = 0, y = 0;   // координаты шара (левого верхнего угла квадрата)
В конструктор Form1() добавим следующие операторы:

this.BackColor = Color.Blue; // цвет формы
buf = new Bitmap(pictureBox1.Width, pictureBox1.Height);
   // Создаем новый экземпляр класса Bitmap c заданным размером
g = Graphics.FromImage(buf);
   // Создает новый графический объект из указанного рисунка
SolidBrush bf = new SolidBrush(Color.White); // перекраска фона
g.FillRectangle(bf, 0, 0, pictureBox1.Width, pictureBox1.Height);
timer1.Enabled = true; // старт таймера

Первый изменяет цвет формы на синий, четыре следующих оператора готовят холст для рисования на pictureBox1, последний запускает в работу таймер (в конструкторе первоначально timer1.Enable=false).  Переменные  g и  buf, объявленные в классе, в конструкторе Form1 конкретизируются: buf получает ссылку на pictureBox1, а g получает ссылку на новый графический объект.  Теперь рисование спрайта-шара будет выполняться именно на поверхности pictureBox1. Координаты окна: (0,0) —  (pictureBox1.Width, pictureBox1.Height) — левый верхний и правый нижний углы.

Рисование шара-спрайта реализуется в методе timer1_Tick( ) с использованием переменной stage и метода  Draw(g, Point(x, y), stage) объекта imageList1.

int stage = 0;    // номер чередующегося шара (красный-0, зеленый-1,             
                     белый-2)
int x = 0, y = 0; // координаты шара (левого верхнего угла квадрата)

private void timer1_Tick(object sender, EventArgs e)
{
   if (stage < 1)
   {
      imageList1.Draw(g, new Point(x, y), 0); // вывести красный 
      stage++;                                // сменить номер шара
   }
   else if (stage < 2)
   {
      imageList1.Draw(g, new Point(x, y), 1); // вывести зеленый
      stage++;                                // сменить номер шара
   }
   else if (stage < 3)
   {
      imageList1.Draw(g, new Point(x, y), 2); // вывести белый квадрат
      stage++;
   }
   else if (stage == 3)     // условие возврата красного шара - 0
   {    
      stage = 0;
      x+=3; y+=2;    // траектория - прямая под углом вниз
   }
   pictureBox1.Image = buf;   // Показать шар
      if (x > pictureBox1.Width) // Возврат в начало
         { x = 0; y = 0; };
   }

GreenSpriteНа холсте — зеленый шар!

Если закомментировать оператор (показать шар), то никаких изображений мы не увидим. Оно, конечно, формируется в паре объектов «g–buf» и в любой момент может появиться на холсте через вызов этого оператора.  Последний оператор после прохождения шаром диагонали возвращает его в начальную позицию для продолжения. Поэкспериментируйте!


NEW: Наш Чат, в котором вы можете обсудить любые вопросы, идеи, поделиться опытом или связаться с администраторами.


Помощь проекту:

Понравилась статья? Поделиться с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
4 комментариев
Новые
Старые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А какой смысл — в использовании компонента PictureBox (кроме его длины по X и высоте по Y) ?

Вместо PictureBox — для этих целей вполне могла бы подойти структура Point — для хранения пар чисел x,y.

Прошу прощения, не увидел самого главного (самая последняя строка в обработчике таймера: pictureBox1.Image = buf;

)

а картинки в imageList1 добавить не надо ? они сами появятся? А imageList1 откуда появился? Для новичков вроде писано. Упомянули бы хотя бы слово ToolBox

Важно: Вы можете поддержать проект и автора.
4
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x
()
x