Построение динамических изображений

Нет такой плохой ситуации, которая не могла бы стать еще хуже.

Из законов Мэрфи.

Было бы любопытно увидеть процесс постепенной отрисовки графика функции. График бы "полз", создавая иллюзию анимации. Попробуем поставить в цикл расчета функции команду задержки Sleep(100), останавливающую программу на 100мс:

...

WHILE Xmin<=Xmax DO

BEGIN

Sleep(100);

y:=sin(xmin);

. ..

Нажимаем F9 и… ничего не изменилось, только расчет стал выполняться медленнее, но график все равно отображается только в самом конце. Почему? Здесь мы столкнулись с одной важной особенностью программ на Delphi: при работе цикла никаких действий с элементами интерфейса не выполняется. Они как бы накапливаются и затем выполняются все сразу. Что же делать? Надо сказать Delphi, чтобы он не ленился и даже в цикле производил перерисовку нашего графика. Делается это просто – достаточно в теле цикла записать команду Application.ProcessMessages. Вот теперь все получилось, график красиво "ползет".

Анимация в Delphi

Вероятность того, что бутерброд упадет маслом вниз,

прямо пропорциональна стоимости ковра.

Из законов Мэрфи.

Давайте изобразим звездное небо, по которому летит летающая тарелка. При этом нужно сделать настоящую анимацию с автоматическим восстановлением фона под движущейся картинкой.

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

procedure TForm1.Button1Click(Sender: TObject);

VAR i:WORD;

Begin

WITH Image1.Canvas DO

BEGIN

Brush.Color:=clBlack;

FillRect(Image1.ClientRect);

FOR i:=1 TO 500 DO

Pixels[RANDOM(Image1.Width), RANDOM(Image1.Height)]:=clWhite

END

end;

Сначала весь холст заливается черным цветом, а затем на нем вы случайных местах отображаются 500 звезд. Для изображения отдельной точки можно использовать свойство объекта Canvas – массив Pixels[x,y], обеспечивающий прямой доступ к цвету точки с координатами x,y.

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

procedure TForm1.Button1Click(Sender: TObject);

PROCEDURE Ufo(x,y:INTEGER);

BEGIN

WITH Image1.Canvas DO

BEGIN

Pen.Color:=clBlue;

Pen.Width:=3;

Ellipse(x,y,x+20,y+10)

END

END;

VAR i:WORD;

...

Обратите внимание, что процедура Ufo должна находиться внутри процедуры TForm1.Button1Click потому, что иначе она не будет иметь доступа к экранной форме Form1. Из-за особенностей работы с анимацией цвет летающей тарелки на экране будет вовсе не синим. Тарелка изобразится цветом, получающимся в результате выполнения операции "логическое ИЛИ" над цветом фона и изображения. В данном случае тарелка окажется желтого цвета, что вполне приемлемо.

Осталось организовать движение тарелки по экрану. Делается это примерно так:

Pen.Mode:=pmNOTXOR;

FOR i:=0 TO Image1.Width DO

BEGIN

Ufo(i, i DIV 2);

Application.ProcessMessages;

Sleep(10);

Ufo(i, i DIV 2)

END

END;

Самая важная строчка в этом фрагменте - Pen.Mode:=pmNOTXOR. Она устанавливает режим вывода графики "исключающее ИЛИ". При таком режиме вывод одной и той же картинки дважды в одно и то же место изображения приводит к автоматическому восстановлению фона под картинкой. В цикле картинка выводится первый раз (вызов процедуры Ufo), затем выполняется команда Application.ProcessMessages, обеспечивающая немедленное отображение НЛО на экране и делается задержка на 10мс, чтобы мы успели увидеть, что получилось. Далее НЛО выводится в то же самое место еще раз, при этом изображение тарелки пропадет, а под ней автоматически восстановится фон.

Координаты тарелки меняются и по Х, и по Y, поэтому она поедет по экрану вправо вниз.

Запускаем… Красиво? Нет! Экран безобразно мерцает. Что делать? Спокойно, это просто еще один фокус Delphi. Чтобы динамическое изображение на форме не мерцало, в начало процедуры вывода анимации надо добавить строчку

Form1.DoubleBuffered:=TRUE;

Вот теперь наш мультик будет смотреться вполне неплохо.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: