Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа №22.pdf
Скачиваний:
30
Добавлен:
16.03.2015
Размер:
1.63 Mб
Скачать

Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»

При изменении размеров формы необходимо модифицировать размер изображения находящегося в буфере, для чего необходимо внести следующие изменения в обработчик события OnResize.

procedure TfrmClock.FormResize(Sender: TObject); begin

//размер изображения в буфере

Buffer.Width:=ClientWidth;

Buffer.Height:=ClientHeight; //рассчитываем радиус циферблата

if ClientWidth>ClientHeight then r:=ClientHeight div 2-10 else r:=ClientWidth div 2-10;

//перерисовать окно

InvalidateRect(Handle, nil, False); end;{FormResize}

Внесите изменения в обработчик события OnPaint формы.

procedure TfrmClock.FormPaint(Sender: TObject); begin

//рисование изображения в буфер

ClockPaint(Buffer.Canvas);

//копирование содержимого буфера на холст формы

Canvas.Draw(0, 0, Buffer); end;{FormPaint}

Запустите программу, проверьте корректность ее работы.

Использование спрайтов

Использование компонента TImage

Для формирования изображения можно использовать не только набор таких примитивов как линии и фигуры, но и изображения. Небольшие изображения, которые выводятся на другое изображение – фон, называются спрайтами. Вывод спрайтов можно осуществить несколькими способами. Начнем с самого простого из них – вывод спрайтов с помощью компонента TImage. Основной проблемой при выводе спрайтов является то, что растр содержащий спрайт имеет прямоугольную форму, а сам спрайт может иметь сложную форму. При выводе спрайта на изображение фона необходимо чтобы пикселы растра содержащего спрайт принадлежащие спрайту замещали пиксели фона, а остальные пикселы не изменяли бы фон (прозрачные пикселы). В компоненте TImage для работы со спрайтами удобно применять свойство Transparent (прозрачность). Если значение свойства равно True, то все пикселы, цвет которых совпадает с цветом пиксела находящегося в левом нижнем углу растра, будут прозрачными, т.е. при выводе изображения не будут копироваться (рисунок 3 и 4).

Создайте новый проект. На форму frmAirPlane поместите компонент TImage (Background). Загрузите в его свойство Picture изображение. Установите значение свойства AutoSize=True для компонента Background.

Поместите на форму еще один компонент TImage (Sprite). Загрузите в него изображение и установите значение свойства Transparent равным True, а значение (рисунок 4).

Поместите на форму таймер установите Interval=50 и создайте обработчик события

OnTimer.

...

var frmAirPlane: TfrmAirPlane;

Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»

implementation var dx:Integer=10;

{$R *.dfm}

procedure TfrmAirPlane.TimerTimer(Sender: TObject); begin

//сдвигаем спрайт вправо

Sprite.Left:=Sprite.Left+dx;

//если достигли правой границы, то переходим в начало if Sprite.Left+Sprite.Width-20>ClientWidth then dx:=-dx; if Sprite.Left<0 then dx:=-dx;

end;{TimerTimer}

Рисунок 3 – Вывод спрайта, выведены все пикселы растра (cвойство Transparent=False).

Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»

Рисунок 4 – Вывод спрайта, выведены только пикселы растра принадлежащие спрайту (свойство

Transparent=True)/

Запустите программу. Сразу видны недостатки такого способа создания анимации, а именно заметное мерцание во время воспроизведения анимации. Устранить такое мерцание не возможно, поэтому перейдем к рассмотрению более совершенных способов создания анимации.

Использование маски спрайта

Следующий способ вывода спрайтов основан на использовании маски для определения тех точек спрайта которые будут выводится при печати спрайта. Маска представляет собой черно-белое изображение спрайта. Черные точки находятся в тех местах спрайта, которые будут выводится, а белые в «прозрачных» местах спрайта. Алгоритм вывода спрайта следующий:

Выводится маска спрайта. Вывод осуществляется в режиме холста cmSrcAnd (свойство CopyMode). В этом режиме при копировании выводятся только пикселы имеющие черный цвет. Таким образом, в фоновом изображении вырезается область по форме спрайта (рисунок 5).

Рисунок 5 – Вывод маски спрайта

Далее по этим же координатам выводится изображение спрайта в режиме cmSrcPaint. В этом режиме пикселы спрайта выводятся только там, где цвет пикселов фона черный (рисунок 6). Таким образом, каждый спрайт состоит из двух изображений: маски спрайта и изображения спрайта.

Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»

Рисунок 6 – Вывод спрайта

Рассмотрим пример программы использующий эту технику вывода спрайтов.

Создайте новый проект. На форму frmAirPlane поместите таймер Timer. Установите интервал срабатывания таймера равным 50 мс. В программе анимируется движение изображения самолета. Движение происходит по случайной траектории. Алгоритм работы программы очень прост и не нуждается в пояснениях. Полный текст программы приведен ниже.

Листинг 1

unit UPlane;

interface

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, Jpeg, ImgList;

type

TfrmAirPlane = class(TForm) Timer: TTimer;

procedure FormCreate(Sender: TObject); procedure FormPaint(Sender: TObject); procedure TimerTimer(Sender: TObject); procedure FormDestroy(Sender: TObject);

private

{Private declarations } public

{Public declarations } Mask, //маска спрайта Sprite,//изображение спрайта

BackGround:TBitmap; //фон

x, y:Integer; //текущие координаты спрайта

//рисует сцену

procedure DrawScene(ACanvas:TCanvas); //рисование спрайта

procedure DrawSprite(x, y:Integer; ACanvas:TCanvas); //расчет координат спрайта

procedure CalcNewCoord(var newX, newY:Integer); //загрузка изображений

procedure LoadImages; end;

var frmAirPlane: TfrmAirPlane;

implementation

{$R *.dfm}

procedure TfrmAirPlane.FormCreate(Sender: TObject); begin

//двойная буферизация

Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»

DoubleBuffered:=True; //загрузка изображений

LoadImages; //расчет координат

CalcNewCoord(x, y); end;{FormCreate}

procedure TfrmAirPlane.FormPaint(Sender: TObject); begin

//рисуем кадр

DrawScene(Canvas); end;{FormPaint}

procedure TfrmAirPlane.DrawScene; begin

with ACanvas do begin

//стираем фон

CopyMode:=cmSrcCopy;//режим копирования CopyRect(ClipRect, BackGround.Canvas,

BackGround.Canvas.ClipRect); //выводим спрайт

DrawSprite(x, y, ACanvas); end;{with}

end;{DrawScene}

procedure TfrmAirPlane.DrawSprite(x, y: Integer; ACanvas:TCanvas);

begin

with ACanvas do begin

//вывод маски спрайта CopyMode:=cmSrcAnd;//режим копирования для маски

Draw(x, y, Mask);

//вывод спрайта

CopyMode:=cmSrcPaint;//режим копирования для спрайта

Draw(x, y, Sprite); end;{with}

end;{DrawSprite}

procedure TfrmAirPlane.LoadImages; begin

//загрузка фона

BackGround:=TBitmap.Create; BackGround.LoadFromFile('background.bmp'); //загрузка маски спрайта

Mask:=TBitmap.Create; Mask.LoadFromFile('Mask.bmp'); //загрузка спрайта

Sprite:=TBitmap.Create; Sprite.LoadFromFile('Sprite.bmp');

end;{LoadImages}

procedure TfrmAirPlane.TimerTimer(Sender: TObject); begin

//расчет следующего положения спрайта

CalcNewCoord(x, y); //перерисовать изображение