Обобщённое программирование в C#. Анимация объектов в диалоговых Windows-приложения. Способы создания

Автор работы: Пользователь скрыл имя, 18 Марта 2012 в 18:27, курсовая работа

Описание

Приложения с графикой, игры, Computer Aided Design/Computer Aided Manufacture (CAD/CAM — проектирование/производство с помощью компьютера), программы для рисования, для создания графиков и многие другие типы приложений требуют от разработчиков написания кода для работы с графикой. Использование создаваемых пользователем управляющих элементов также предполагает работу с графикой.

Содержание

Введение……………………………………………………………………….3

Глава1. Принципы работы с графикой средствами GDI+

1.1 Пространство имён GDI+ …………………………………...…4
1.2 Пространство имен System.Drawing ………………………......5
1.3 Служебные типы System.Drawing …………………………......6
1.4 Возможности класса Graphics ……………………………….....7
1.5 Обзор пространства имен System. Drawing. Drawing2D …..9
1.6. Вывод изображений …………………………………………..10

Глава 2. Способы создания анимации объектов

2.1 Метод перемещения …………………………………11
2.2 Таймер ...……………………………………………...13


Глава3. Практическая работа «Часики» ………………………..14

Заключение …………………………………………………27

Литература ………………………………………………….28

Работа состоит из  1 файл

курсовая.doc

— 234.50 Кб (Скачать документ)

1.6. Вывод изображений

Для вывода изображения на форму в нашем распоряжении есть два способа. Первый заключается в том, что мы напрямую дописываем необходимую логику в метод OnPaint(). Второй (более предпочтительный) предусматривает перехват события Paint.

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

Иногда возникает необходимость инициировать перерисовку изображения на форме вручную (иными словами, программным образом поместить в очередь сообщений сообщение о необходимости перерисовки). Например, в нашей программе может быть предусмотрено диалоговое окно для выбора пользователем изображения. После того как пользователь выберет то, что ему нужно, форму необходимо будет перерисовать, чтобы отобразить выбранное изображение.

Для того чтобы инициировать перерисовку формы программным образом, используется метод Invalidate(). 

      Существует множество перегруженных вариантов метода Invaldate(). Например, мы можем указать конкретную прямоугольную область, подлежащую перерисовке, вместо всей клиентской части формы (она перерисовывается по умолчанию).

Очень часто бывает так, что вывод графического объекта необходимо произвести не в стандартных ситуациях, когда возникает событие Paint, а в ответ на другие события. Например, предположим, что наша задача — вывести маленький кружок в том месте, где на форме был сделан щелчок мышью. Первая наша задача, как всегда при выводе изображений, — получить объект Graphics, а затем выполнить с этим объектом необходимые манипуляции. Объект Graphics можно получить при помощи метода Graphics. FromHwnd (). Обратите внимание, что единственный параметр, передаваемый этому методу, — это значение свойства Handle. Свойство Handle, как говорилось в предыдущей главе, определено в классе Control и наследуется всеми классами, производными от Control.

Легко убедиться на практике, что при любой перерисовке формы (возникновении события Paint) все кружки, выведенные на форме после щелчков мышью, исчезнут. Это не удивительно, поскольку, как мы видим, вывод графических объектов (кружков) в нашем случае происходит только в результате щелчка мышью, но не при выводе формы на экран.

Скорее всего, в реальном приложении потребуется не только выводить какие-либо графические объекты на форму, но и сохранять их при перерисовке формы — мы же не хотим, чтобы они пропадали, например, при перекрытии формой окном другого приложения? Поэтому нам придется позаботиться о том, чтобы информация о графических объектах каким-то образом сохранялась и использовалась при перерисовке формы. Самый простой способ — создать внутреннюю коллекцию (например, при помощи класса ArrayList) и помещать туда нужные нам объекты. Затем к этой коллекции будет обращаться метод OnPaintC).

Таким образом, использование метода Graphics . FromHwnd ( ) — это очень удобный способ получить объект Graphics без использования события Paint.

 

 

 

 

ГЛАВА 2.    Способы создания анимации объектов

2.1 Метод перемещения

Мы часто сталкиваемся с проблемой перемещения картинки(Image) по форме. Решить ее можно тремя способами (может есть и больше, но я знаю только три).

Его суть заключается в том, что свойства Left и Top картинки изменяются на разницу между начальными и конечными  координатами (нажатия и отпускания мыши соответственно). Этот способ самый простой и надежный, но у него есть один недостаток: left и top изменяются по очереди, что приводит к заметному мерцанию картинки. Тем не менее мы этот способ рассмотрим. Не забудьте положить на форму Image и вставить в нее какую-нибудь картинку. Для начала необходимо объявить глобальные переменные (они объявляются в разделе Implementation) x0, y0:integer - они будут запоминать начальные координаты. И еще нам понадобится переменная move типа boolean, чтобы нам отличать перемещение мыши над картинкой, от попытки ее сдвинуть.

Этот способ довольно прост, как для понимания, так и для реализации. Но такой же алгоритм перемещения можно реализовать немного красивее. У некоторых компонентов, в том числе и Image, есть такая процедура SetBounds(Left,Top,Width,Height), которая может изменять сразу все четыре параметра. Таким образом событие OnMouseMove можно изменить так:

 

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

begin

if move then begin

image1.SetBounds(image1.Left+x-x0,image1.Top+y-y0,image1.width,image1.height);

end;

end;

 

Но есть еще один очень интересный выход: по экрану можно перемещать не саму картинку, а только ее рамку, когда пользователь выберет место для картинки и отпустит кнопку - она туда переместиться. Для этого нам понадобится еще одна глобальная переменная: rec: TRect, которая будет хранить параметры картинки. Теперь слегка изменим обработчики событий для картинки. Таким образом все в целом будет выглядеть так:

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

if button<>mbLeft then move:=false

else begin

move:=true;

x0:=x;

y0:=y;

rec:=image1.BoundsRect; //запоминаем контур картинки

end;

end;

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

begin

if move then begin

Form1.Canvas.DrawFocusRect(rec); //рисуем рамку

with rec do begin

left:=Left+x-x0;

top:=Top+y-y0;

right:=right+x-x0;

bottom:=bottom+y-y0;

x0:=x;

y0:=y; // изменяем координаты

end;

Form1.Canvas.DrawFocusRect(rec); // рисуем рамку на новом месте

end;

end;

 

procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

Form1.Canvas.DrawFocusRect(rec);

with image1 do begin

setbounds(rec.left+x-x0,rec.top+y-y0,width,height); //перемещаем картинку

move:=false;

end;

end;  

Поскольку DrawFocusRect рисует рамку методом Xor, то при повторном вызове этой функции с теми же параметрами, рамка стирается.

 

2.2 Таймер

Таймер — это устройство, периодически уведомляющее приложение о завершении заданного интервала времени. Ваша программа устанавливает этот интервал, как бы говоря: «'Предупреждай меня каждую десятую долю секунды», — и таймер вызывает обработчик события десять раз в секунду.

В пространствах имен System.Timers, System.Threading и SystemWindowsforms определены три разных класса с именем Timer. Я буду использовать тот, что определен в пространстве SystemWindowsforms. С этим таймером программисты для Microsoft Windows знакомы лучше всего. Он совмещен с другими событиями Windows и наиболее прост в использовании.

Хотя таймер и не столь важное устройство ввода, как клавиатура или мышь, он все же может быть очень полезен и находит применение во многих приложениях Windows Forms. Наиболее очевидным приложением для таймера является программа-часы, и в этой главе таких программ будет предостаточно. Однако есть и другие, возможно, не такие очевидные области применения таймера.

• Многозадачность Хотя Windows является средой с вытесняющей многозадачностью, рекомендуется, чтобы после обработки события программы возвращали управление Windows как можно быстрее. Иначе темп может существенно замедлиться. Если программа должна выполнить большой объем работы, ее можно разделить на несколько частей и выполнять каждую часть по получении события таймера.

• Обновление данных Таймер подходит для обновления постоянно изменяющейся информации, например, при выводе данных о свободных ресурсах или проценте выполнения какой-либо задачи.

• Автосохранение Таймер позволяет периодически сохранять на диске результаты работы программы.

• Прекращение работы демо-версий программ. Некоторые демо-версии программ самостоятельно завершаются, скажем, через 30 минут после запуска. В таких приложениях таймер подает сигнал на прекращение работы. (Пример такой программы, CloselnFive)

• Пошаговое продвижение. Обычно необходимо с заданной скоростью перемещать графические объекты в игре или переключать страницы в программах-описаниях. Таймер помогает избежать несовместимости, связанной с разными скоростями процессоров. Таймер часто применяют в анимации.

Таймер можно рассматривать и как гарант, обеспечивающий передачу управления программе. Если после выполнения конструктора или обработчика события программа отдает управление, обычно нельзя определить, когда произойдет следующее событие. В этом смысле событие таймера более определенно. Я сказал более, потому что таймер не обладает ритмичностью метронома. События, вырабатываемые классом Timer, синхронизированы с другими событиями.

Иначе говоря, событие таймера никогда не прервет процедуру обработки другого события, выполняющуюся в том же потоке. Если обработка события идет слишком долго, она задержит событие таймера.

Класс Timer

Класс Timer невелик и относительно прост. Обычно объект Timer создается конструктором по умолчанию:

Timer timer = new Timer();

 

 

Глава3

Практическая работа «Часики»

Данная работа построена на основе пространства имен GDI+ (System.Drawing, System,Drawing,Drawing2D ).

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Drawing.Drawing2D;

namespace WindowsFormsApplication5

{

        public partial class Form1 : Form

    {

        float nowradX = 92;

        float nowradY = 114;

      

//Блок поворота маятника

        double angle = 0.0; 

        bool to_the_left = true;

        int max_angle = 24;

        int max_angle2 = -18;

        //Конец блока Pendulum

        //-------------------------------------------

  float x2S = 92,x2M = 92,x2H = 92; //координаты дополнений

  float y2S = 15,y2M = 15,y2H = 15;

  int fi = -90,fiM = -90;

  float fiH = -90;

  int r = 70;

  bool startindx = true; //переменная ограничения области прорисовки по координатам

int hour = 0, second = 0, minute = 0,indXM = 0,indXH = 0;

bool pm_am = false; //если pm = false,если am = true;

        //переменные для работы будильника

int AlarmHour = 0, AlarmMin = 0, AlarmSec = 0;

        //Кисти

        Pen myPenSec = new Pen(Color.Black, 1);

        Pen myPenMin = new Pen(Color.Black, 3);

        Pen myPenHou = new Pen(Color.Black, 5);

        //--переменные по режимам

        bool modeRTime = true, modePeTime = false;

        //три режима работы- таймер,аналоговые часы,пользовательское время

        public Form1()

        {

            InitializeComponent();

            //установка максимумов(Часов ,минут,секунд)

            numericUpDown1.Maximum = 24;

            numericUpDown1.Minimum = 0;

            numericUpDown1.TabStop = false;

            //-------------------------------

            numericUpDown2.Maximum = 59;

            numericUpDown2.Minimum = 0;

            numericUpDown2.TabStop = false;

            //------------

            numericUpDown3.Maximum = 59;

            numericUpDown3.Minimum = 0;

            numericUpDown3.TabStop = false;

            //-----------

            numericUpDown4.Maximum = 24;

            numericUpDown4.Minimum = 0;

            numericUpDown4.TabStop = false;

            //------------

            numericUpDown5.Maximum = 59;

            numericUpDown5.Minimum = 0;

            numericUpDown5.TabStop = false;

            //---------------

            numericUpDown6.Maximum = 59;

            numericUpDown6.Minimum = 0;

            numericUpDown6.TabStop = false;

            //--------

            button1.Enabled = false;

            button3.Enabled = false;

        }

 

        //---------------

        //Блок поворота картинки

public static Image RotateImage(Image img, double rotationAngle)

        {

//Создание переменной бмп без рисунка размером 230 на 700

            Bitmap bmp = new Bitmap(230, 700);

            //Превод в другой класс

            Graphics gfx = Graphics.FromImage(bmp);

            //Определение центра трансформации gfx.TranslateTransform((float)bmp.Width / 2, 0);

            //Изменение изображения, поворот маятника

   gfx.RotateTransform((float)rotationAngle);

   gfx.TranslateTransform(-(float)bmp.Width / 2, -100);

  gfx.InterpolationMode =terpolationMode.HighQualityBicubic;

  gfx.DrawImage(img, new Point(bmp.Width / 2, 100));

            //dispose of our Graphics object

            gfx.Dispose();

            Bitmap bmp2 = new Bitmap(230, 700);

            Graphics g2 = Graphics.FromImage(bmp2);

            g2.DrawImage((Image)bmp, new PointF(30, 0));

            //

            //ВОЗВРАТ ИЗОБРАЖЕНИЯ

            g2.Dispose();

            return bmp2;

        }//конец блока поворота

        //---------------

        

private void numericUpDown1_ValueChanged(object sender, EventArgs e) //объект таймер-задание времени

        {

            if (((numericUpDown1.Value == 0)

                && (numericUpDown2.Value == 0) && (numericUpDown3.Value == 0)))

            {button3.Enabled = false;  }

            else { button3.Enabled = true; 

                timer4.Enabled = false;

                button6.Enabled = false;

            }

        }//--------------------------------

 

private void button1_Click(object sender, EventArgs e) //старт

        {

     if(modePeTime) //пользовательское время

            {

             if(!timer3.Enabled)//если таймер 3 не работает

                  {

                    if (startindx)

                    {

         //----Инициализация начальных координат стрелки

Информация о работе Обобщённое программирование в C#. Анимация объектов в диалоговых Windows-приложения. Способы создания