Программирование с нуля - это совсем просто! 176) Программирование ролевой игры : Отображение карты
Школа программирования
176) Программирование ролевой игры: Отображение карты в Windows
Предыдущий выпуск по ролевой игре, был N 172.
Мы не будем, как уже говорилось, в данной теме останавливаться на технике быстрого графического вывода, а воспользуемся стандартными возможностями и компонентами Delphi, в частности, компонентом PaintBox и его канвой для отображения карты и игрового мира. Интересующихся техникой быстрого спрайтового вывода в рамках обычного окна Windows со стандартными элементами управления (в отличие от графических библиотек DirectX/OpenGL, работающих в полноэкранном режиме) в очередной раз отсылаю за бесплатной библиотекой
g32.org.
Какого размера будет компонент TPaintBox на форме? Мы уже условились, что видимая часть составит 20*16 клеток размером 32*32 пиксела каждая, то есть 640*512 точек. Такой размер и укажем в нашем объекте PaintBox на форме.
Начнем с процедуры ShowCell, которая отображает конкретный тайл. Для этого, очевидно, нам потребуются изображения каждого тайла, которые мы для простоты сделаем простыми квадратиками разных цветов (всего 10). Эти изображения в качестве растровых элементов должны быть загружены один раз на этапе создания программы. Пусть они будут храниться в главной форме в качестве массива TileBits:
public
{ public declarations }
IsGame, RealTimeFlag: Boolean;
TileBits: array[0..tileLast] of TBitmap; end;
В момент создания формы в данный массив загрузим изображения из файлов (они, условимся, будут называться 0.bmp, 1.bmp, 2.bmp, .. , 10.bmp):
// ----- procedure TGameForm.FormCreate(Sender: TObject); var i: Integer; begin
IsGame:=false;
for i := 0 to tileLast do begin
TileBits[i] := TBitmap.Create;
TileBits[i].LoadFromFile( IntToStr(i) + ' .bmp ' ); end; end; //
Что такое 0.bmp? Ведь нумерация тайлов у нас начинается с единицы? В этом тайле будем хранить "изображение" полностью невидимой для игрока клетки, которая еще не открыта. Пусть соответствующий файл будет содержать чистый черный квадрат.
Можно также вынести все загружаемые ресурсы в отдельный каталог, чтобы не сваливать все файлы в одну кучу. Тогда в команде загрузки квадратика надо добавить путь к нему, например:
gfx - это подкаталог в текущем каталоге, в который складываем все *.bmp файлы.
Сколько тайлов нам потребуется? 12, включая нулевой черный.
Все, что надо сделать в процедуре ShowCell - это отобразить соответствующий рисунок в правильном месте канвы. Воспользуемся сначала ранее подготовленным для DOS-версии кодом, рассчитывающим целые (в целых клетках, а не пикселах) координаты:
x := WINDOW_LEFT+x-GameMap[CurMap].LocalMapLeft;
y := WINDOW_TOP+y-GameMap[CurMap].LocalMapTop;
Далее переведем их в пикселы и выводим в соответствующем месте канвы объекта TPaintBox картинку тайла:
x := (x-1)*32;
y := (y-1)*32;
GameForm.PaintBox.Canvas.Draw(x,y, GameForm.TileBits[t.Tile] );
Желательно также учесть видимость/невидимость клетки, для чего мы и подготовили файл 0.bmp:
{ ----------------- } procedure ShowCell(t: TMapCell; x,y: Integer); begin
x := WINDOW_LEFT+x-GameMap[CurMap].LocalMapLeft;
y := WINDOW_TOP+y-GameMap[CurMap].LocalMapTop;
x := (x-1)*32;
y := (y-1)*32;
if t.IsVisible then GameForm.PaintBox.Canvas.Draw(x,y, GameForm.TileBits[t.Tile] ) else GameForm.PaintBox.Canvas.Draw(x,y, GameForm.TileBits[0] ); //
невидимый тайл
end;
Только, чтобы изображение не "уезжало" за границы формы, выставим в качестве значений констант, определяющих смещение образа карты относительно границ, нули:
{$IFDEF WIN_GAME}
const WINDOW_LEFT = 0;
WINDOW_TOP = 0;
В принципе, такого кода, этих пяти операторов уже вполне достаточно для отображения всей карты в Windows! Что в очередной раз свидетельствует о правильноти нашей исходной программной архитектуры.
Напомним, что все действия по выводу карты выполняются в процедуре ShowGame. Windows устроена таким образом, что при необходимости перерисовки экнара (например, после свертывания и последующего развертывания окна) ему посылается сообщение, которое программист должен обрабатывать. В нашем случае это будет событие OnPaint компонента PaintBox, в обработчике которого надо указать вызов основной процедуры отображения:
// ----- procedure TGameForm.PaintBoxPaint(Sender: TObject); begin if not IsGame then Exit;
ShowGame; end; //
Здесь мы вставили проверку переменной IsGame, которую создали специально для данного случая - ведь вызыать ShowGame можно только тогда, кода выполнена процедура начала игры, а это может произойти отнюдь не сразу после открытия формы.
Чтобы в самый первый раз вызвать отображение карты, добавим вызов ShowGame; в процедуру начала новой игры:
// новая игра -- procedure TGameForm.NewGameItemClick(Sender: TObject); begin
RealTimeFlag:= false;
Randomize;
Все эти учебные курсы рассчитаны не только на разработчиков, но и на всех тех, кто хочет стать ИТ-менеджером. Для этого как минимум нужно иметь общее представление о современных технологиях разработки и их истории и владеть соответствующей терминологией. Именно это мои книги и дают.
В учебных курсах описаны десятки технологий, каждой из которых посвящены отдельные книги. Таким образом, купив один учебный курс, вы существенно сэкономите :) В книгах полностью описаны:
- Delphi (версия 2006, полностью совместимая с Delphi 2005/2006/2007 и Turbo Delphi) для обеих платформ - Win32 и .NET;
- C# (новый язык Microsoft, на котором базируется платформа .NET и все новые версии Windows);
- C++ для платформы Win32.
Охвачены также темы работы с файлами на этих платформах, создания файл-серверных, клиент-серверных, распределенных приложений, веб-программ (Indy, ASP.NET, веб-сервисы). Описаны языки SQL и OCL. Немало глав посвящены истории программирования и различных технологий. Особое внимание уделено созданию программ с помощью технологии ECO и языка моделирования UML - программы фактически рисуются, и теперь даже для создания корпоративных приложений и их переноса в Интернет не обязательно знать программирование!
Отдельная часть отведена технологиям организации групповой работы, управления требованиями, контроля версий, локализации и тестирования.
Тут подробнее про книги.