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

Создание ролевой компьютерной игры 14) Рюкзак и инвентарь


Информационный Канал Subscribe.Ru

Разработка ролевой игры

14) Рюкзак и инвентарь

Складываем предметы в рюкзак

Теперь все готово для реализации самой, пожалуй, важной части программы - сражений. Пока нам остается выполнить заключительный этап подготовки к бою и научить героя использовать оружие и одевать броню. Добавим в структуру THero массив Items, представляющий собой набор предметов, несомых героем в рюкзаке. Максимальный объем рюкзака ограничим 12 предметами.

Такой способ ограничения объема рюкзака не совсем точен. В коммерческих играх обычно применяется один из двух более совершенных подходов или их комбинация. Во-первых, пространство рюкзака может быть представлено в виде прямоугольника, разбитого на квадратики.

Каждый предмет в игре в таком случае имеет определенную форму, выраженную в виде таких квадратиков.

Играющему нередко приходится решать немало головоломных задач, связанных с оптимальным распределением предметов в рюкзаке.

Второй подход более простой. Подразумевается, что каждый предмет в игре имеет свой вес. Герой может либо нести ограниченный вес, но теоретически неограниченное число предметов, либо неограниченный вес, который однако влияет на различные характеристики персонажа. Так, слишком тяжелый рюкзак замедляет скорость передвижения, повышает расход энергии, ухудшает внимательность (навык обнаружения ловушек) и ловкость в бою и т. д.

Хорошая игра сочетает оба эти подхода. Первый вариант сложен для реализации и возможен, только если игра создается с графическим интерфейсом. Теоретически, конечно, возможен вариант, когда мы используем текстовый режим для размещения предметов на экране по координатам текстовых символов. Наибольшие затруднения при этом возникают, когда мы попытаемся реализовать алгоритм интерфейсного управления размещением предметов в рюкзаке, который будет удобен пользователю только в том случае, если он может использовать мышь для перетаскивания предметов в режиме "перетащи и оставь". В ДОСе реализовать это посложнее, чем в Windows, поэтому текстовые бродилки используют вариант, подразумевающий простое ограничение характеристик героя по мере роста веса несомых предметов. Читатель может самостоятельно выбрать один из подходов или их комбинацию для программирования.

  const MaxHeroItems = 12;

  type THero = record
       Chars : array[1..MaxChars] of Integer;
       Skills: array[1..MaxSkills] of Integer;
       Items : array[1..MaxHeroItems] of TGameItem;
       x,y,
       HP, MaxHP,
       Exp, MaxExp,
       Level, VisLong: Integer;
       end;

Инициализация данного массива происходит в процедуре InitHero. Как нам определить, что некоторый слот массива Items пустой? Ранее мы решили использовать для этого поле x записи TGameItem (если оно равно нулю, значит, предмет пустой). Однако с учетом растущих требований к функциональным возможностям программы желательно сделать такую проверку более гибкой и более точно соответствующей логике нашего приложения. Поэтому расширим описание типа TGameItemType (список типов предметов, модуль GameItem) новым значением itemNone, соответствующем понятию "предмета нет":

  type TGameItemType = (itemHandWeapon, itemArmor, itemNone);

Место, где выполнялось занесение нуля в поле x, теперь можно исправить (процедура MapGeneration, модуль Map).

Было:

  for i := n+1 to MaxItems do
      Items[i].x := 0;

Стало:

  for i := n+1 to MaxItems do
      Items[i].IType := itemNone;

Инициализация рюкзака запишется так:

  procedure InitHero(HeroNum: Integer);
  var i: Integer;
  begin

  with Heroes[HeroNum] do
    begin
    for i := 1 to MaxChars do
      Chars[i] := 0;
    for i := 1 to MaxSkills do
      Skills[i] := BaseSkill_Table[i];
    for i := 1 to MaxHeroItems do
      Items[i].IType := itemNone;
  ...

Отступление.

При попытке компиляции программы в модуле LowLevel возникнет ошибка. Это сработал наш автоматический уведомитель необходимости расширения списка отображаемых на экране предметов.

Здесь необходимо добавить в массив ItemRecords еще один элемент для отображения "пустого" предмета:

  const ItemRecords: array[TGameItemType] of TTileRecord =
     (
     (C: ' + ' ; Clr:LightCyan),
     (C: ' [ ' ; Clr:LightGreen),
     (C: ' ' ; Clr:Black)
     );

Очевидно, что такой элемент отображать не надо, да и программа никогда не будет его выводить. Однако формальное описание требует любого (производльного) описания.

Отображать содержимое рюкзака станем в новой процедуре ShowHeroItems (модуль LowLevel):

  procedure ShowHeroItems;
  var i: Integer;
  begin
  ClrScr;
  GoToXY(1,1);
  Write(STR_HERO_ITEMS);
  for i := 1 to MaxHeroItems do
    begin
    GoToXY(1,i+2);
    if Heroes[CurHero].Items[i].IType = itemNone
       then Write(i, ' ) ' ,STR_EMPTY_ITEM)
       else Write(Heroes[CurHero].Items[i].Name)
    end;
  GoToXY(1,20);
  ReadLn;
  ShowGame;
  end;

Чтобы экран содержимого рюкзака не накладывался на текущее изображение, предварительно очистим его и выведем сообщение-заголовок. Затем в цикле пробежимся по всем ячейкам рюкзака, и если в i-й ячейке найдется предмет, покажем его название в соответствующей строке. В противном случае сообщим (STR_EMPTY_ITEM), что ячейка рюкзака пуста.

Вызывать данную процедуру будем из главного модуля программы Main - там, где происходит обработка нажатий пользователя на клавиши. Отведем для показа содержимого рюкзака клавишу (символ) i:

  ...
  while true do
    begin
    ShowGame;
    k := ReadKey;
    case k of

       ' i ' : ShowHeroItems;
  ...

Новые текстовые константы:

     const
            STR_HERO_ITEMS = ' Предметы Героя ' ;
            STR_EMPTY_ITEM = ' <пусто> ' ;

Давайте снабдим героя в начале игры двумя предметами - легкой броней и недорогим топором.

Окончание реализации рюкзака - в следующем выпуске.

Исходный код текущей версии (всегда проверен и работоспособен, главный файл- main.pas):

http://russianenterprisesolutions.com/sbo/download/25105.zip 6926 байтов


(c) 2004-2005 Сергей Бобровский bobrovsky@russianenterprisesolutions.com

Школа программирования с нуля
Все предыдущие выпуски базового курса тут:
http://russianenterprisesolutions.com/sbo/

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


Subscribe.Ru
Поддержка подписчиков
Другие рассылки этой тематики
Другие рассылки этого автора
Подписан адрес:
Код этой рассылки: comp.soft.prog.prognull.game
Архив рассылки
Отписаться
Вспомнить пароль

В избранное