Графические возможности Delphi: Мультипликация, использование ьиотвых образов

Мультипликация

 

Под мультипликацией обычно понимается движущийся и меняющийся рисунок. В простейшем случае рисунок может только двигаться или только меняться.

Как было показано выше, рисунок может быть сформирован из графических примитивов (линий, окружностей, луг, многоугольников и т. д.). Обеспечить перемещение рисунка довольно просто: надо сначала вывести рисунок на экран, затем через некоторое время стереть его и снова вывести этот же рисунок, но уже на некотором расстоянии от его первоначального положения. Подбором времени между выводом и удалением рисунка, а также расстояния между старым и новым положением рисунка (шага перемещения), можно добиться того, что у наблюдателя будет складываться впечатление, что рисунок равномерно движется по экрану. {replace on}

Следующая простая программа, текст которой приведен в листинге 10.8, а вид формы — на рис. 10.15, демонстрирует движение окружности от левой к правой границе окна программы.

Рис. 10.15. Форма программы Движущаяся окружность

Листинг 10.8. Движущаяся окружность

 

01.unit mcircle ;
02.interface
03.uses
04.Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls;
05.type
06.TForml = class(TForra)
07.Timer1: TTimer;
08.procedure TimerlTimer(Sender: TObject);
09.procedure FormActivatejSender: TObject);
10.private
11.{Private declarations }
12.public
13.{ Public declarations }
14.end;
15.implementation
16.{$R *.DEW}
17.var
18.Form1; TForm;
19.x,y: byte// координаты центра окружности
20.dx: byte// приращение координаты х при движении окружности
21.// стирает и рисует окружность на новом месте
22.procedure Ris;
23.begin
24.// стереть окружность
25.fоml.Canvas.Pen.Color:=forml.Color;
26.forml.Canvas.Ellipse [x,y,x+10,y+10) ;
27.x:=x+dx;
28.// нарисовать окружность на новом месте
29.forml.Canvas.Pen.Color:=c!Black;
30.forml.Canvas.Ellipse(х,у,x+10,y+10);
31.end;
32.// сигнал or таймера
33.procedure TForml.TimerlTiroer(Sender: TObject];
34.begin
35.Ris;
36.end;
37.procedure TForml.FormActivate(Sender: TObject);
38.begin
39.y:=10;
40.dx:=5;
41.tirnerl. Interval: =50// период возникновения события OriTimer — 0.5 сек
42.forml.canvas.brush.color:=forml.color;
43.end;
44.end.

 

Основную работу выполняет процедура RIS, которая стирает окружность и выводит ее на новом месте. Стирание окружности выполняется путем перерисовки окружности поверх нарисованной, но цветом фона.

Для обеспечения периодического вызова процедуры Ris в форму программы добавлен невизуальный компонент Timer (таймер), значок которого находится на вкладке System палитры компонентов (рис. 10.16). Свойства компонента Timer, перечислены в табл. 10.9.

Рис. 10.16. Значок компонента Timer


Добавляется компонент Timer к форме обычным образом, однако, поскольку компонент Timer является невизуальным, т. е. во время работы программы не отображается на форме, его значок можно поместить в любое место формы.

Таблица 10.9, Свойства компонента Timer

Компонент Timer генерирует событие OnTimer. Период возникновения события OnTimer измеряется в миллисекундах и определяется значением свойства interval. Следует обратить внимание на свойство Enabled. Оно дает возможность программе "запустить" или "остановить" таймер. Если значение свойства Enabled равно False, то событие OnTimer не возникает.

Событие OnTimer в рассматриваемой программе обрабатывается процедурой TimeriTimer, которая, в свою очередь, вызывает процедуру Ris. Таким образом, в программе реализован механизм периодического вызова процедуры Ris.
 
 
Примечание: Переменные х, у (координаты центра окружности) и dx (приращение координаты х при движении окружности) объявлены вне процедуры Ris, т. е. они являются глобальными. Поэтому надо не забыть выполнить их инициализацию (в программе инициализацию глобальных переменных реализует процедура FormActivate).

 Метод базовой точки

 

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

При программировании сложных изображений, состоящих из множестваэлементов, используется метод, который называется методом базовой точки.

Суть этого метода заключается в следующем: 

  1. Выбирается некоторая точка изображения, которая принимается за базовую.
  2. Координаты остальных точек отсчитываются от базовой точки.
  3. Если координаты точек изображения отсчитывать от базовой в относительных единицах, а не в пикселах, то обеспечивается возможность масштабирования изображения.

На рис. 10.17 приведено изображение кораблика. Базовой точкой является точка с координатами (x0, y0). Координаты остальных точек отсчитываются именно от этой точки.

Рис. 10.17. Определение координат изображения относительно базовой точки 

 

В листинге 10.9 приведен текст программы, которая выводит на экран изображение перемешающегося кораблика.

Листинг 10.9. Кораблик

 

01.unit ship_;
02.interface
03. 
04.uses
05.Windows, Messages, SysOtils, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls, ExtCtrls;
06.type
07.TForml = class(TForra)
08.Timer!: TTiraer;
09.procedure TimerlTimer(Sender: TObject];
10.procedure FormActivate(Sender: TObject);
11.private
12.{ Private declarations }
13.public
14.{ Public declarations }
15.end;
16.var
17.Form1: TForm1;
18.x,y: integer// координаты корабля (базовой точки)
19.implementation
20.{SR *.DFM}
21.// вычерчивает кораблик
22.procedure Titanik(x,y: integer// координаты базовой точки
23.color: TColor]; // цвет корабля
24.const
25.dx - 5;
26.dy = 5;
27.var
28.buf: TColor;
29.begin
30.with forml.canvas do
31.begin
32.buf:=pen.Color; // сохраним текущий цвет
33.pen.Color:=color; // установим нужный цвет
34.// рисуем . . .
35.// корпус
36.MoveTo(x,y] ;
37. 
38.LineTo(к,y-2*dy);
39.LineTo(x+10*dx,y-2*dy);
40.LineTo(x+ll*dx,y-3*dy) ;
41.LineTo(x+17*dx,y~3*dy);
42.LineTo (x+1-4*dx,y);
43.LineTo(x,y);
44.// надстройке
45.MoveTo(x+3*dx,y-2*dy);
46. 
47.LineTo(x+4*dx,y-3*dy) ;
48.LineTo (x+4*dx, y-4dy);
49.LineTo(x+13*dx,y-4*dy);
50.LineTo(x+13*dx,y-3*dy);
51.MoveTo (x-f5*dx, y-3*dy) ;
52.LineTo (x+9*dx,y-3*dy);
53.// капитанский мостик
54. 
55.Rectangle(x+8*dx,y-4*dy,x+ll*dx,y-5*dy|;
56.// труба
57.Rectangle(x+7*dx,y-4*dy,x+8*dx,y-7*dy);
58.// иллюминаторы
59.Ellipse(x+ll*dx,y-2*dy,x+12*dx,y-l'dy);
60.Ellipse (x+13*dx,y-2*dy,x-t-14*dx,y-l*dy) ;
61.// мачта
62.MoveTo(x+10*dx,y-5'dy);
63.LineTo (x-HO*dx,y-10*dyi ;
64.// оснастка
65.MoveTo(x+17*dx,y-3*dy);
66.LineTo(x+10*dx,y-10*dy| ;
67.LineTo(x,y-2*dy);
68.pen.Color:=buf; // восстановим старый цвет карандаша
69.end;
70.end;
71.// обработка сигнала таймера
72. 
73.procedure TForml.TimerlTiiner(Sender: TObject];
74.begin
75.Titanik{x,y,forml.color); // стереть рисунок
76.if x < Form1.ClientWidth then x := x+5 else begin // новый рейс
77.x := О;
78.у := Random(50] + 100;
79.end;
80.Titanik(x,y,clffliite); // нарисовать в новой точке
81.end;
82.procedure TForml.FormActivatelSender: TObject);
83.begin
84.x:=0;
85.y:=100;
86.Forml.Color:=clNavy;
87.Timer1.Interval := 50// сигнал таймера каждые 50 миллисекунд
88.end;
89.end.

 

 

Отрисовку и стирание изображения кораблика выполняет процедура Titanik, которая получает в качестве параметров координаты базовой точки и цвет, которым надо вычертить изображение кораблика. Если при вызове процедуры цвет отличается от цвета фона формы, то процедура рисует кораблик, а если совпадает— то "стирает". В процедуре Titanik объявлены константы dx и dy, определяющие шаг (в пикселах), используемый при вычислении координат точек изображения. Меняя значения этих констант, можно проводить масштабирование изображения.


Использование битовых образов

 

В предыдущем примере изображение формировалось из графических при-
митивов. Теперь рассмотрим, как можно реализовать перемещение одного
сложного изображения на фоне другого, например перемещение самолета
на фоне городского пейзажа.
Эффект перемещения картинки может быть создан путем периодической
перерисовки картинки с некоторым смещением относительно ее прежнего
положения. При этом предполагается, что перед выводом картинки в новой

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

Эффект перемещения картинки может быть создан путем периодической перерисовки картинки с некоторым смещением относительно ее прежнегоположения. При этом предполагается, что перед выводом картинки в новой точке сначала удаляется предыдущее изображение. Удаление картинки может быть выполнено путем перерисовки всей фоновой картинки или только той ее части, которая перекрыта битовым образом движущегося объекта. 

В рассматриваемой программе используется второй подход. Картинка выводится применением метода Draw к свойству canvasкомпонента image, a стирается путем копирования (метод CopyRect) нужной части фона из буфера на поверхность компонентаimage. 

Форма программы приведена на рис. 10.18, а текст — в листинге ШЛО. 

Компонент image используется для вывода фона, а компонент Timer — для организации задержки между циклами удаления и вывода на новом месте изображения самолета.

Листинг 10.10. Летящий самолет

 

01.unit anim_;
02.interface
03.uses
04.Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
05.Dialogs, ExtCtrls, StdCtrls, Buttons;
06.type
07.TForml = class(TForm)
08.Timerl: TTimer;
09.Irnagel: TImage;
10.procedure ForraActivate(Senderr TObject);
11.procedure TimerlTimer(Sender: TObject);
12.procedure FormClose(Sender: TObject; var Action: TCloseAction);
13.private
14.{ Private declarations }
15.public
16.{ Public declarations}
17.end;
18.var
19.Forml: TForm;
20.implementation
21.{$R*.DFM}
22.var
23.Back, bitmap, Buf : TBitMap; // фон, картинка, буфер
24.BackRct : TRect; // область фона, которая должна быть
25.// восстановлена из буфера
26.BufRct: Ttect; // область буфере, которая используется для
27.// восстановления фона
28.х,у:integer// текущее положение картинки
29.W,H: integer// размеры картинки
30.procedure TForml.FormActivatefSender: TObject);
31.begin
32.// создать три объекта — битовых образа
33.Back := TBitmap.Create; // фон
34.bitmap := TBitmap.Create; // картинка
35.Buf := TBitmap.Create; // буфер
36.// загрузить и вывести фон
37.Back.LoadFromFilei'factory.bmp'J;
38.Forml.Imagel.canvas.Draw(0,0,Back);
39.// загрузить картинку, которая будет двигаться
40.bitmap.LoadFromFile('aplane.bmp');
41.// определим "прозрачный" цвет
42.bitmap.Transparent := True;
43.bitmap.TransParentColor := bitmap.canvas.pixels[1,1];
44.// создать буфер длл сохранения копии области фона,
45.// на которую накладывается картинка
46.W:= bitmap.Width;
47.Н:= bitmap.Height;
48.Buf.Width;= W;
49.Buf.Height:=H;
50.Buf.Palette:=Back.Palette; // Чтобы обеспечить соответствие палитр ! !
51.Buf.Canvas.CopyMode:=cmSrcCopy;
52.// определим обласгь буфера, которая будет использоваться
53.// для восстановления фона
54.BufRet:^Bounds(0,0,W,H);
55.// начальное положение картинки
56.к := -W;
57.у := 20;
58.// определим сохраняемую область фона
59.BackRct:=Bounds(x,у,W,H);
60.// и сохраним ее
61.Buf.Canvas.CopyRect(BufRct,Back.Canvas,BackRct);
62.end;
63.// обработка сигнала таймера
64.procedure TForml.TimerlTimer(Sender: TObject);
65.begin
66.// восстановлением фона (из буфера) удалим рисунок
67.Forml.imagel.canvas.Draw(x,у,Buf);
68.x:=x+2;
69.if x>forml.Imagel.Width than x:=-W;
70.// определим сохраняемую область фона
71.BackRct:=Bounds(x,у,W,H);
72.// сохраним ее копию
73.Buf.Canvas.CopyRect(BufRet,Back.Canvas,BackRct];
74.// выведем рисунок
75.Forml.imagel.canvas.Draw(x,у,bitmap);
76.end;
77.// завершение работы программы
78.procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
79.begin
80.// освободим память, выделенную
81.// для хранения, битовых образов
82.Back.Free;
83.bitmap. Free;
84.Buf.Free;
85.end;
86.end.

 

Рис. 10.18. Форма программы Самолет 

 

Для хранения битовых образов (картинок) фона и самол dle


Помоги проекту! Расскажи друзьям об этом сайте: