Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Создание ролевой компьютерной игры 52) Отображение карты в Windows


Школа программирования

52) Программирование ролевой игры: Отображение карты в Windows

Мы не будем, как уже говорилось, в данной теме останавливаться на технике быстрого графического вывода, а воспользуемся стандартными возможностями и компонентами 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? Ведь нумерация тайлов у нас начинается с единицы? В этом тайле будем хранить "изображение" полностью невидимой для игрока клетки, которая еще не открыта. Пусть соответствующий файл будет содержать чистый черный квадрат.

Можно также вынести все загружаемые ресурсы в отдельный каталог, чтобы не сваливать все файлы в одну кучу. Тогда в команде загрузки квадратика надо добавить путь к нему, например:

   TileBits[i].LoadFromFile( ' gfx\ ' + IntToStr(i) + ' .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;

   MapGeneration(1);
   GenerateMonsters;
   InitHeroes;
   IsGame:=true;

   GenerateHero;

   ShowGame;
  end; //

В следующем занятии следом за картой аналогичным образом запрограммируем отображение в игре персонажа, монстров и предметов.

Текущий исходный код проекта (для Дельфи 7, включая bmp-тайлы :), всегда проверен и работоспособен:
d160807.zip , 24600 байтов


(c) 2004-2007 Сергей Бобровский : bo собака russianenterprisesolutions.com

Школа программирования с нуля
Все предыдущие выпуски базового курса всегда тут:
http://www.infiltration.ru/p/

Неофициальный сайт поддержки (со срочными вопросами - сюда):
www.prog-begin.net.ru.


Мои книги (учебные курсы) "Технологии Delphi / C++ / C#".
http://shop.piter.com/publish/authors/17681/191180213/

Все эти учебные курсы рассчитаны не только на разработчиков, но и на всех тех, кто хочет стать ИТ-менеджером. Для этого как минимум нужно иметь общее представление о современных технологиях разработки и их истории и владеть соответствующей терминологией. Именно это мои книги и дают.
В учебных курсах описаны десятки технологий, каждой из которых посвящены отдельные книги. Таким образом, купив один учебный курс, вы существенно сэкономите :) В книгах полностью описаны:
- Delphi (версия 2006, полностью совместимая с Delphi 2005/2006/2007 и Turbo Delphi) для обеих платформ - Win32 и .NET;
- C# (новый язык Microsoft, на котором базируется платформа .NET и все новые версии Windows);
- C++ для платформы Win32.
Охвачены также темы работы с файлами на этих платформах, создания файл-серверных, клиент-серверных, распределенных приложений, веб-программ (Indy, ASP.NET, веб-сервисы). Описаны языки SQL и OCL. Немало глав посвящены истории программирования и различных технологий. Особое внимание уделено созданию программ с помощью технологии ECO и языка моделирования UML - программы фактически рисуются, и теперь даже для создания корпоративных приложений и их переноса в Интернет не обязательно знать программирование!
Отдельная часть отведена технологиям организации групповой работы, управления требованиями, контроля версий, локализации и тестирования.
Тут подробнее про книги.

Мои книги, которые пока доступны в продаже:


Дизайн рассылки: Алексей Голубев - Web-дизайн и web-программирование


В избранное