Движение гусеницы

Caterpillar

Задача : создать приложение, выводящее на экран анимированное изображение
Использованный API : .NET Framework 3.5
Язык : Visual C#
Среда разработки : MS Visual Studio 2008

Приложение выводит на экран форму, в клиентской области которой находится анимированная картинка.
Технологии изображения
Для создания эффекта анимации использован объект System.Windows.Forms.Timer с интервалом в 80 единиц времени (миллисекунд). Обработчик события таймера OnTick вызывает метод Invalidate(), который делает недействительным содержимое формы. Вследствие этого возникают события OnPaint и OnPaintBackground.Обработчик события OnPaintBackground вырисовывает солнце и траву. Обработчик события OnPaint отрисовывает гусеницу.
Для отрисовки спирали на солнце использована функция, заданная в полярных координатах.
Два гребня травы хранятся в массиве точек System.Drawing.Point и выводятся как полигон вдоль нижней границы клиентской области формы пока не встретится ее правый край.
Движение гусеницы имитируется путем поочередного сжатия сегментов тела гусеницы. После одного прохода сжатия последний элемент оказывается сдвинутым на несколько пикселов относительно начального положения.

//File Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
 
namespace Caterpillar
{
    public partial class Form1 : Form
    {
        //массив точек представляющий траву
        private Point[] grass = null;
        //количество элементов гусеницы
        int n;
        //номер сжиающегося элемента
        int s = 0;
        //точка начала отрисовки гусеницы
        int xc, yc;
 
        public static void Main()
        {
            using (Form1 frm = new Form1())
            {
                frm.Show();
                Application.Run(frm);
            }
        }
        //Конструктор формы
        public Form1()
        {
            InitializeComponent();
            //Установка стилей отрисовки. Необходима для избежания мигания формы
            this.SetStyle(ControlStyles.AllPaintingInWmPaint |
                ControlStyles.UserPaint |
                ControlStyles.ResizeRedraw |
                ControlStyles.OptimizedDoubleBuffer,
                true);
 
            //настройка таймера
            timer1.Interval = 80;
            timer1.Tick += new EventHandler(TimerOnTick);
            timer1.Start();
 
            s = 0;
            n = 7;
            xc = 50;
            yc = ClientSize.Height - 75;
        }
        //Обработчик события Paint. Вызывается, когда содержимое формы становится недействительным(Invalidated)
        //Отрисовывает основной слой формы
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Caterpillar(e.Graphics);
        }
        //Обработчик события PaintBackground.
        //Отрисовывает фон содержимого формы, поверх которого рисуется основной слой
        protected override void OnPaintBackground(PaintEventArgs e)
        {
            base.OnPaintBackground(e);
            Background(e.Graphics);
        }
        //Обработчик события таймера Tick.
        private void TimerOnTick(object sender, EventArgs e)
        {
            //Делает содержимое формы недействительным, что приводит к возникновению событий PaintBackground и Paint
            Invalidate();
        }
        //Функция отрисовки фона
        private void Background(Graphics g)
        {
            //Создание кисти(Brush) для закрашивания(Fill) плоских фигур
            Brush brush = new SolidBrush(Color.LimeGreen);
 
            //Установка сглаживания изображения
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
 
            //Инициализация массива для отрисовки травы
            grass = new Point[5];
            grass[0] = new Point(0, this.ClientRectangle.Height);
            grass[1] = new Point(20, this.ClientRectangle.Height - 40);
            grass[2] = new Point(40, this.ClientRectangle.Height);
            grass[3] = new Point(60, this.ClientRectangle.Height - 70);
            grass[4] = new Point(80, this.ClientRectangle.Height);
            //Отрисовка травы. Продолжается пока не выйдет за пределы клиентской области формы
            do
            {
                g.FillPolygon(brush, grass, System.Drawing.Drawing2D.FillMode.Winding);
                for (int i = 0; i < 5; i++)
                {
                    grass[i].X += 80;
                }
            } while (grass[0].X < this.Width);
            //Отрисовка круга для солнца
            g.FillEllipse(new SolidBrush(Color.Yellow),
                this.ClientRectangle.Width - 80, 10, 70, 70);
            //Переменные, необходимые для отрисовки спирали, заданной в полярных координатах(Rho = Phi)
            float x0, y0, x1, y1;
            double t = 0;
            //Вычисление начальной позиции отрисовки спирали
            x0 = (float)(t * Math.Cos(t) + this.ClientRectangle.Width - 45);
            y0 = (float)(t * Math.Sin(t) + 45);
            //Вычисляются две точки спирали и соединяются прямой
            while (t < Math.PI * 11)
            {
                //Приращение угла для/и вычисления следующей точки
                t += 0.02;
 
                x1 = (float)(t * Math.Cos(t) + this.ClientRectangle.Width - 45);
                y1 = (float)(t * Math.Sin(t) + 45);
                g.DrawLine(new Pen(Color.Red),
                    x0, y0, x1, y1);
                x0 = x1;
                y0 = y1;
            }
        }
        //Отрисовка гусеницы
        private void Caterpillar(Graphics g)
        {
            //Установка высоты, на которой расположена гусеница
            yc = ClientSize.Height - 75;
            //Создание кисти для заполнения
            Brush brush = new SolidBrush(Color.DarkGreen);
            //Когда сжимающийся элемент достигает головы, процесс начинается сначала, и гусеница перемещается
            if (s >= n)
            {
                s = 0;
                xc += 8;
            }
            //При выходе из клиентской области гусеница полностью перемещена в левую часть формы
            if (xc > this.Width)
                xc = 0;
            //Отрисовка хвостовых круглых элементов
            for (int i = 0; i < s; i++)
                g.FillEllipse(brush,
                    xc + i * 32, yc,
                    35, 35);
            //Отрисовка сжатого элемента
            g.FillEllipse(brush,
                xc + s * 32, yc,
                25, 32);
            //Отрисовка передних круглых элементов
            for (int i = 0; i < n - s; i++)
                g.FillEllipse(brush,
                    xc + 24 + s * 32 + i * 32, yc,
                    35, 35);
 
            //Перерисовка гусеницы слева от клиентской области
            //Обеспечивает плавное выползание гусеницы слева
            if (this.ClientSize.Width - xc < n * 35)
            {
                for (int i = 0; i < s; i++)
                    g.FillEllipse(brush,
                        -ClientSize.Width + xc + i * 32, yc,
                        35, 35);
 
                g.FillEllipse(brush,
                    -ClientSize.Width + xc + s * 32, yc,
                    25, 32);
 
                for (int i = 0; i < n - s; i++)
                    g.FillEllipse(brush,
                        -ClientSize.Width + xc + 24 + s * 32 + i * 32, yc,
                        35, 35);
            }
            //Переход к следующему сжимающемуся элементу
            s++;
        }
    }
}
 
 
//File Form1.Designer.cs
namespace Caterpillar
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;
 
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
 
        #region Windows Form Designer generated code
 
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.timer1 = new System.Windows.Forms.Timer(this.components);
            this.SuspendLayout();
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(384, 262);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);
 
        }
 
        #endregion
 
        private System.Windows.Forms.Timer timer1;
    }
}

Ключевые слова: 
анимация гусеница ,net framework
ВложениеРазмер
Caterpillar.rar50.08 кб