Программный модуль

К файлу модуля Unit1.h (Листинг 1.1) добавлено описание структуры FigureType, включающей позицию (X,Y), смещение (DX,DY) фигуры и номер объекта спрайта (SD); а в секцииpublic класса формы объявлены четыре переменные размеров изображений, две фигуры Fig [2] и соответствующие им две пары спрайтов Sprite [4]. Класс SpriteClass и его методы определены в файлах Sprite.h и Sprite.cpp, соответственно.

ttifndef UnitlH

#define UnitlH

#include <vcl\Classes.hpp> ttinclude <vcl\Controls.hpp> ftinclude <vcl\StdCtrls.hpp>

#include <vc1\Forms.hpp> ttinclude "sprite.h"

#include <vcl\Buttons.hpp> ftinclude "sampreg.h" ftinclude <vcl\Dialogs.hpp>

typedef struct { int X, Y, DX, DY, SD; } FigureType;

class TFormI: public TForm (

_published: // IDE-managed Components TPaintBox *PaintBox;

TImage *DrawBox;

TImage *Background;

TImage *Figures;

TTimer *Timerl;

TPanel * Panel 1;

TSpeedButton *SpeedButtonl;

TSpeedButton *SpeedButton2;

TSpeedButton *SpeedButton3;

TSpinEdit *SpinEditl;

TOpenDialog *OpenDialog;

void _fastcall TimerlTimer(TObject * Sender);

void _fastcall SpinEditlKeyUp(TObject *Sender, WORD &Key, TShiftState Shift);

void _fastcall SpinEditlKeyDown(TObject * Sender,

WORD &Key, TShiftState Shifts-void_fastcall SpeedButtonlClick(TObject *Sender) ;

void_fastcall SpeedButton2Click(TObject * Sender);

void_fastcall SpeedButton3Click(TObject * Sender);

private: // User declarations public: // User declarations _fastcall TFormI(TComponent* Owner);

int W, H, w, h;

FigureType Fig[2];

SpriteClass Sprite[4];

};

extern TFormI *Forml;

#endif

Листинг 1.1. Содержание файла Unii1.h.

 

Файл модуля Unit1.cpp (Листинг 1.2) содержит 5 обработчиков событий от нажатия кнопок управления и обработчик события таймера.

//-_---------_____________-___-_-----__-____________________-

^include <vcl\vcl.h>

#pragma hdrstop

#include "Unitl.h"

#pragma link "sampreg"

#pragma resource "*.dfm" TFormI *Forml;

//----------------——--——--—------———------—-----------

_fastcall TFormI::TFormI(TComponent* Owner) : TForm(Owner) ( // Конструктор формы устанавливает размеры по умолчанию W = Н = 400; w = h =61;

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

void_fastcall TFormI::SpeedButtonlClick(TObject *Sender)

{ if (OpenDialog->Execute())

{ // Открыть файл изображения фона

Background->Picture->LoadFromFile(OpenDialog->FileName) ;

W = Background->Picture->Width;

H = Background->Picture->Height;

}

} //----—----------——-------—-——---—-—-—-------------

void_fastcall TFormI::SpeedButton2Click(TObject *Sender) { if (OpenDialog->Execute())

{ // Открыть файл изображения фигур

Figures->Picture->LoadFromFile(OpenDialog->FileName);

w = (Figures->Picture->Width)/6;

h = Figures->Picture->Height;

//______---------------------------------------------------

void_fastcall TFormI::SpeedButton3Click(TObject *Sender)

{ // Инициализировать поля структуры обеих фигур Fig[0].X = W/4; Fig[l].X = 3*W/4;

Fig[0].Y = H/4; Fig[l].Y = 3*H/4;

Fig[0].DX = 1; Fig[l].DX = -1;

Fig[0].DY = 1; Fig[l].DY = -1;

Fig[0].SD = 0; Fig[l].SD = 0;

// Подготовить экземпляры спрайта

Sprite[0].SetSprite(Figures->Canvas, 0,0, 4*w,0, w,h);

Sprite[1].SetSprite(Figures->Canvas, 2*w,0, 4*w,0, w,h);

Sprite[2].SetSprite(Figures->Canvas, w,0, 5*w,0, w,h);

Sprite[3].SetSprite(Figures->Canvas, 3*w,0, 5*w,0, w,h) ;

Timerl->Enabled = true;

}

void _fastcall TFormI::SpinEditlKeyUp(TObject *Sender,

WORD &Key, TShiftState Shift) { Timerl->Interval++; } void _fastcall TFormI::SpinEditlKeyDown(TObject *Sender,

WORD &Key, TShiftState Shift) { Timerl->Interval--; } //-.____-_-_-_-_.....____.__________________________________

int Shift = 0; // переменная прокрутки фона void _fastcall TFormI::TimerlTimer(TObject *Sender) ( // Сместить фигуры в пределах периметра

Fig[0].X += Fig[0].DX; Fig[0].Y += Fig[0].DY;

if (Fig[0].X > (W/2-w)) Fig[0].DX = -1;

if (Fig[0].X < 20) Fig[0].DX = 1;

if (Fig[0].Y > (H-2*h)) Fig[0].DY = -1;

if (Fig[0].Y < 20) Fig[0].DY = 1 ;

Fig[l].X += Fig[l].DX; Fig[l].Y += Pig[l].DY;

if (Fig[l].X > (W-w)) Fig[l].DX = -1;

if (Fig[l].X < (W/2+w)) Fig[l].DX = 1;

if (Fig[l].Y > (H-h)) Fig[l].DY = -1;

if (Fig[l].Y < 30) Fig[l].DY = 1 ;

// Оживить фигуры, переключая экземпляр спрайта

Fig[0].SD = (Fig[0].SD == 0) ? 2 : 0;

Fig[l].SD = (Fig[l].SD == 1) ? 3 : 1 ;

// Нарисовать фон и сдвинуть его влево

if (Shift == 0)

{ DrawBox->Canvas->CopyMode = cmSrcCopy;

DrawBox->Canvas->CopyRect(Rect(О, О, W, H),

Background->Canvas, Rect(0, 0, W, H));

}

else

{ DrawBox->Canvas->CopyMod^s = cmSrcCopy;

DrawBox->Canvas->CopyRect(Rect(0, 0, W-Shift, H),

Background->Canvas, Rect(Shift, 0, W, H) ) ;

DrawBox->Canvas->CopyRect(Rect(W-Shift, 0, W, H),

Background->Canvas, Rect(0, 0, Shift, H)) ;

}

Shift += 2;

if (Shift >= W) Shift -= W;

// Нарисовать фигуры на канве внеэкранного битового образа

Sprite[Fig[0].SD].Draw(DrawBox->Canvas,Fig[0].X, Fig[0].Y) ;

Sprite[Fig[l].SD].Draw(DrawBox->Canvas,Fig[1].X, Fig[l].Y) ;

// Скопировать изображение на экран

PaintBox->Canvas->CopyMode = cmSrcCopy;

PaintBox->Canvas->CopyRect(Rect(0, 0, W, H),

DrawBox->Canvas, Rect(0, 0, W, H)) ;

}

Листинг 1.2. Содержание файла Unit1 cpp.

Быстрые кнопки компонент TSpeedButton служат для управления программой. Первая кнопка открывает и загружает объект Background класса TImage из файла с изображением фона (размером w на H). Вторая кнопка открывает и загружает объект Figures класса TImage из файла с изображениями фигур (размером w на h каждая).

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

Нажатие кнопок компоненты редактирования TSpinEdit вызывает увеличение или уменьшение на единицу значения интервала таймера (по умолчанию устанавливается значение 40, соответствующее кадровой частоте 1/25 сек).

Ядром приложения является обработчик события OnTimer объекта Timerl. Первый блок кода реакции на прерывание от таймера отвечает за перемещение фигур, изменяя направление движения всякий раз, когда они "утыкаются" в фиксированные границы отведенного периметра. Рис. 1.2 изображает структуру канвы объектов DrawBox и PaintBox.

Рис.1.2. Структура канвы для рисования движущихся фигур.

Следующий блок реализует прокрутку фона справа-налево, делая анимацию более реальной (можете называть этот процесс" виртуальной реальностью, если хотите). Фигуры могут сходиться и расходиться, но общее впечатление их движения слева-направо сохраняется. Для начала надо скопировать изображение фона целиком в буфер внеэкранного изображения, а затем организовать циклический сдвиг влево данных буфера на величину, установленную переменной Shift. Заключительный блок рисует, при помощи метода Draw, фигуры на канве невидимого объекта DrawBox, а затем копирует изображение канвы на экран, в видимый объект PaintBox.