Рисунок 9. Форма и окно программы "Полет"
private:
System::Drawing::Bitmap^ sky;
System::Drawing::Bitmap^ plane;
// графическая поверхность, на которой формируется изображение
Graphics^ g;
// приращение координаты X, определяет скорость полета
int dx;
// область, в которой находится объект
Rectangle rct;
// генератор случайных чисел
System::Random^ rnd;
// конструктор
public:
Form1(void)
{
InitializeComponent();
try
{
sky = gcnew System::Drawing::Bitmap (Application::StartupPath + "\\sky.bmp");
plane = gcnew System::Drawing::Bitmap (Application::StartupPath + "\\plane.bmp");
}
catch (System::Exception^ e)
{
MessageBox::Show("Ошибка загрузки битового образа: " + e->Message, "Полет",MessageBoxButtons::OK,MessageBoxIcon::Error);
this->Paint += nullptr;
return;
}
// сделать прозрачным фон
plane->MakeTransparent();
// установить размер формы равным размеру фонового рисунка
this->ClientSize = sky->Size;
// задать фоновый рисунок формы
this->BackgroundImage = gcnew Bitmap(sky);
// g — графическая поверхность, на которой будем формировать рисунок
// определяем графическую поверхность
g = this->CreateGraphics();
// инициализация генератора случайных чисел
rnd = gcnew System::Random();
// исходное положение самолета
rct.X = -40; rct.Y = 20 + rnd->Next(20);
rct.Width = plane->Width; rct.Height = plane->Height;
/* скорость полета определяется периодом следования сигналов от таймера и величиной приращения координаты X */
dx = 2; // скорость полета — 2 пиксела/тик_таймера
timer1->Interval = 20; timer1->Enabled = true;
}
// сигнал от таймера
private:System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) {
// Стереть изображение объекта — вывести фрагмент фона
// в ту область графической поверхности, в которой сейчас находится объект
g->DrawImage(sky,
Rectangle(rct.X,rct.Y,rct.Width,rct.Height),
Rectangle (rct.X,rct.Y,rct.Width,rct.Height),
GraphicsUnit::Pixel);
// вычислить новое положение объекта
if (rct.X < this->ClientRectangle.Width) rct.X += dx;
else
{
// объект достиг правой границы, перемещаем его к левой границе
rct.X = -40;
rct.Y = 20 + rnd->Next(40);
// скорость полета от 2 до 5 пикселов/тик_таймера
dx = 2 + rnd->Next(4);
}
// вывести изображение объекта на новом месте
g->DrawImage(plane,rct.X,rct.Y);
}
В рассматриваемой программе фоновый рисунок и изображение объекта загружаются из файлов. Конструктор формы обеспечивает загрузку битовых образов, задает начальное положение объекта, выполняет настройку и запуск таймера. Следует обратить внимание на то, что начальное значение поля X структуры rec, которое определяет положение левого верхнего угла битового образа (движущейся картинки) — отрицательное число, равное ширине битового образа. Поэтому в начале работы программы самолет не виден, картинка отрисовывается за границей видимой области. С каждым событием Tick значение координаты X увеличивается, и на экране появляется та часть битового образа, координаты которой больше нуля. Таким образом, у наблюдателя создается впечатление, что самолет вылетает из-за левой границы окна.
Процедура обработки сигнала от таймера (события Timer) выполняет основную работу. Сначала она стирает изображение объекта (восстанавливает ''испорченный" фоновый рисунок), затем выводит изображение объекта на новом месте. Восстановление фона выполняет метод DrawImage путем вывода фрагмента фонового рисунка (битового образа sky) в область графической поверхности, в которой находится в данный момент объект (рис. 10).
Graphics bitmap
r1 r2
Graphics->DrawImage(bitmap, r1, r2, GraphicsUnit::Pixel)
Рисунок 10. Метод DrawImage позволяет вывести в указанную область графической поверхности фрагмент битового образа
Следует обратить внимание на то, что в функции обработки события Timer для доступа к графической поверхности используется переменная g. Эта переменная хранит ссылку на графическую поверхность окна программы. Ее значение устанавливает конструктор формы: метод CreateGraphics возвращает ссылку на графическую поверхность объекта this, т. е. формы. Такой "хитрый способ используется потому, что доступ к графической поверхности (через параметр e) есть у функции обработки события Paint и, в принципе, выводить графику должна процедура обработки именно этого события. В нашем примере картинка обновляется несколько раз в секунду и перерисовка окна (а именно это делает функция обработки события Paint) привела бы к заметному мерцанию картинки
Достарыңызбен бөлісу: |