Развитие компьютерных технологий пополнило арсенал разработчиков многочисленными программными инструментами, позволяющими заменить целые отрасли в сфере развлечений. Ну а что является "грезами" для компьютерщиков? Конечно, игры. Да, речь пойдет об играх. Вернее, не о них самих, а о том, как их можно создать с помощью подручных средств. Например, с помощью программных пакетов Borland Delphi или Borland C++ Builder.
Средства GDI (Graphics Device Interface) являются неотъемлемой частью операционной среды Windows и предназначены прежде всего для решения коммерческих задач. Но в играх, где кадры должны сменяться 25 раз в секунду, GDI оказывается ужасно неповоротливым.
В Borland Delphi и C++ Builder имеются в наличии VCL (Visual Component Library) - Библиотеки Визуальных Компонент, в составе которых есть и графические элементы. Сами пакеты поддерживают внешние битовые образы, метафайлы и пиктограммы. Вся прелесть работы с Delphi или C++ Builder в том, что у Вас есть возможность создания компонентов или использования уже существующих. И при этом работать можно только с событиями.
Рассмотрим простейший пример написания компьютерной игры, а точнее, создадим основные составляющие любых игр. Это, прежде всего, прокрутка фона и спрайты. Сам процесс я буду описывать для Delphi, так как у него больше приверженцев на территории нашего государства. Хотя все изложенные принципы можно без проблем переложить и в C++ Builder, только изменив синтаксис языка Pascal на С++, что несложно.
Итак, нам нужен фон. Причем для создания ощущения движения потребуется организовать его прокрутку. Для простоты доступа и долго не затрудняя себя поисками, за фоновый файл возьмем имеющийся в каталоге Windows Clouds.bmp (в русской версии Облака.bmp). Он превосходно подходит для примера прокрутки фона. Саму же прокрутку осуществим справа налево. Для этого на основную форму я помещаю компоненту Timage, назвав ее FON. После этого в Object Inspector нахожу свойство Picture и загружаю в него файл Clouds.bmp. Также на основную форму я помещаю компоненту TTimer, назвав ее Timer1, и кнопку TButton для старта прокрутки, назвав ее StartBtn. Вот, в принципе, и все. Теперь дело за обработкой событий.
var Form1: TForm1; I,A,B:INTEGER; implementation {$R *.DFM} procedure TForm1.FormActivate (Sender: TObject); begin I:=0; T1.Enabled:=False; {таймер отключен} A:= FON.Picture.Width; {ширина картинки Clouds.bmp} B:= FON.Picture.Height; {высота картинки Clouds.bmp} end; procedure TForm1.StartBtnClick (Sender: TObject); begin T1.Enabled:=True; {включается таймер} end; procedure TForm1.T1Timer (Sender: TObject); begin if I=0 then FON.Picture.Bitmap.Canvas.CopyRect (Rect(0,0,W,H), FON.Picture.Bitmap.Canvas, Rect(0,0,W,H)); I:=I+1; {задается перемещение} FON.Picture.Bitmap. Canvas.CopyMode:=cmSrcCopy; FON.Picture.Bitmap.Canvas.CopyRect (Rect(0,0,A-I,B), FON.Picture.Bitmap. Canvas,Rect(I,0,A,B)); FON.Picture.Bitmap.Canvas.CopyRect (Rect(A-I,0,A,B), FON.Picture.Bitmap.Canvas, Rect(0,0,I,B)); if I=A then I:=0; {возврат к началу} end; end.
Перед Вами представлена простейшая программа прокрутки фона. Думаю, что ее листинг особых трудностей для понимания не создает. Единственное, чтобы достичь скорости 25 кадров в секунду, свойство TTimer - Interval следует установить равным 40. После нажатия кнопки старта при запуске программы у Вас на основной форме поплывут облака. Чтобы одновременно с прокруткой запускался звук, установите компонент TMediaPlayer с параметрами:
AutoOpen: True; FileName: Вводите имя какого-нибудь звукового файла; Visible: False;
После всего этого в procedure TForm1. StartBtnClick добавляете строчку:
MediaPlayer1.Play;
Если Вы захотите осуществить управление с клавиатуры или мыши, то компоненты TTimer и TButton Вам не понадобятся. Все события будут происходить относительно событий, запускаемых нажатием различных клавиш.
Следующий листинг показывает, как управлять прокруткой фона с помощью клавиши "Пробел". При нажатии на пробел переменная Key устанавливается в vk_Space (vk обозначает Virtual Key). Все коды виртуальных клавиш находятся в блоке Windows.
procedure TForm1.FormKeyDown (Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key=vk_Space then begin I:=I+1; FON.Picture.Bitmap.Canvas.CopyMode:=cmSrcCopy; FON.Picture.Bitmap.Canvas.CopyRect (Rect(0,0,A-I,B), I1.Picture.Bitmap.Canvas, Rect(I,0,A,B)); FON.Picture.Bitmap.Canvas.CopyRect (Rect(A-I,0,A,B), I1.Picture.Bitmap.Canvas, Rect(0,0,I,B)); if I=A then I:=0; end; end;
Клавиша "Пробел" выбрана "от фонаря", Вы можете заменить ее любой другой. От этого конечный результат не изменится. Таким же образом с помощью управления с клавиатуры можно смоделировать прокрутку фона слева-направо, снизу-вверх и сверху-вниз. Принцип аналогичен. Также можно одновременно крутить несколько фоновых полей, то есть наложить друг на друга несколько компонентов TImage, установив свойство Transparent в True (сделать прозрачными).
Теперь спрайты. Что же это такое? Помните, в детстве с помощью нескольких листков бумаги и карандаша мы создавали мультики? На каждом листике рисовались разные фазы движения какого-либо объекта, и потом с помощью карандаша мы меняли видимые рисунки. В результате получался мультик. Так вот, сами того не осознавая, мы создавали спрайты. Спрайты - это графические объекты, отражающие различные фазы движения фигуры. На рисунке представлен пример такого спрайта.
Здесь видны фазы выстрела пушки и изменения лица. Все изображения банка данных спрайта должны быть одинакового размера. Теперь устанавливаем компоненту TImage так, чтобы она отражала первую из фаз. После этого по методу, схожему с прокруткой фона, начинаем делать анимацию. В данном примере я не буду выносить спрайты как отдельный класс, а просто поработаю с графическим файлом.
var Form1: TForm1; I,A,B,B1:integer; implementation {$R *.DFM} procedure TForm1.FormActivate (Sender: TObject); begin I:=0; A:=IMAGE.Picture.Width; {ширина картинки Sprite.bmp} B:=IMAGE.Picture.Height; {высота картинки Sprite.bmp} B1:=B/5; {всего пять фаз движения} end; procedure TForm1.FormKeyDown (Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key=vk_Space then begin I:=I+B1; IMAGE.Picture.Bitmap. Canvas.CopyMode:=cmSrcCopy; IMAGE.Picture.Bitmap. Canvas.CopyRect(Rect(0,0,A,B-I), IMAGE.Picture.Bitmap.Canvas, Rect(0,I,A,B)); FON.Picture.Bitmap. Canvas.CopyRect(Rect(0,B-I,A,B), IMAGE.Picture.Bitmap. Canvas,Rect(0,0,A,I)); if I=B then I:=0; end; end;
Компоненту TImage я назвал IMAGE. Получившийся "мультик" можно прокрутить с помощью клавиши пробел. Однако можно написать подобную программу и с помощью TTimer. Преимуществом использования TTimer является возможность изменения скорости прокрутки анимации. Когда Вы создадите нечто подобное, то попробуйте фон рисунков спрайта поменять на черный и наложить IMAGE на какой-нибудь внешний фон. В результате у Вас получится приличная мультипликация.
Конечно, открыв любую книгу по Delphi, Вы обнаружите множество сложных описаний и разделений на различные классы и подпрограммы, но на поверхности понятия спрайта лежит именно такое представление. Поэтому необязательно погружаться в строки кода, а лишь осознать принцип действия, ну а дальше, как говорится, - Объектно-Ориентированное Мышление.
Кристофер М. ИХИХО,
аранжировщик "S-MEDIUM DX"
Горячие темы