Урок 14. Рюкзак и инвентарь Складываем предметы в
рюкзак (47 стр)
Теперь все
готово для реализации самой, пожалуй, важной части программы - сражений. Пока
нам остается выполнить заключительный этап подготовки к бою и научить героя
использовать оружие и одевать броню. Добавим в структуру ТНerо массив Items, представляющий собой
набор предметов, несомых героем в рюкзаке. Максимальный объем рюкзака ограничим
12 предметами.
Такой способ
ограничения объема рюкзака не совсем точен. В коммерческих играх обычно
применяется один из двух более совершенных подходов или их комбинация.
Во-первых, пространство рюкзака может быть представлено в виде прямоугольника,
разбитого на квадратики.
Каждый
предмет в игре в таком случае имеет определенную форму, выраженную в виде таких
квадратиков.
Играющему
нередко приходится решать немало головоломных задач, связанных с оптимальным
распределением предметов в рюкзаке.
Второй подход
более простой. Подразумевается, что каждый предмет в игре имеет свой вес. Герой
может либо нести ограниченный вес, но теоретически неограниченное число
предметов, либо неограниченный вес, который, однако, влияет на различные
характеристики персонажа. Так, слишком тяжелый рюкзак замедляет скорость
передвижения, повышает расход энергии, ухудшает внимательность (навык
обнаружения ловушек) и ловкость в бою и т. д.
Хорошая игра
сочетает оба эти подхода. Первый вариант сложен для реализации и возможен,
только если игра создается с графическим интерфейсом. Теоретически, конечно,
возможен вариант, когда мы используем текстовый режим для размещения предметов
па экране по координатам текстовых символов. Наибольшие затруднения при этом
возникают, когда мы попытаемся реализовать алгоритм интерфейсного управления
размещением предметов в рюкзаке, который будет удобен пользователю только в том
случае, если он может использовать мышь для перетаскивания предметов в режиме
"перетащи и оставь". В ДОСе реализовать это посложнее, чем в Windows,
поэтому текстовые бродилки используют вариант, подразумевающий простое
ограничение характеристик героя по мере роста веса несомых предметов. Читатель
может самостоятельно выбрать один из подходов или их комбинацию для
программирования.
const MaxHeroItems = 12;
type
THero = record
Chars :.array[1..MaxChars] of
Integer;
Skills :array [ 1 ..MaxSkills].. of
Integer;
Item : array [1 . .MaxHeroItems] of
TGameltem;
Begin
HP:=MaxHP;
Exp:=MaxExp;
End;
Действие
данного массива происходит в процедуре InitHero. Как нам определить, что Items пустой?
Ранее мы решили использовать для этого поле х MaxHeroItems (если
оно равно нулю, значит, предмет пустой). Однако с учетом требований к функциональным
возможностям программы желательно сделать ее более гибкой и более точно
соответствующей логике нашего приложения описание типа TGameltem Type (список
типов предметов, модуль со значением itemNone, соответствующем понятию
"предмета нет":
HandItemType = (itemHandWeapon, itemArmor,
itemNone);
Чтобы
выполнялось занесение нуля в поле х, теперь можно исправить (процедура модуль Map).
For i:=1 to MaxItems do
Items[i].n:=0;
For j:=1 to MaxItems do
Items[i].IType:=itemNone;
Заполнение рюкзака запишется так:
Procedure InitHero (HeroNum:Integer)
;
Var I:Integer;
Begin
For i:=1 to MaxChars do
Items[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[TGameltemType] of TTileRecord =
(
( ‘ : ’ / CLR:.LightCyan)
( ‘ ; ’ / CLR :LightGreen)
( ‘ | ’ / CLR:Black)
);
Такой элемент
отображать не надо, да и программа никогда не будет его выводить. Однако
формальнoe описание требует любого (производльного) описания, и мое рюкзака
станем в новой процедуре ShowHeroIlems
(модуль …)
procedure ShowHeroItems;
var i: Integer;
begin
ClrScr; GoToXY(1,1);
Write(STR_HERO_ITEMS);
for i := 1 to MaxHeroItems do begin
GoToXY(l,i+2);
if
Heroes[CurHero].Items[i].IType
= itemNone then
Write(i, '
) ' ,STR_EMPTY_ITEM)
else
Write(Heroes[CurHero].Items[i].Name)
end;
GoToXY(l,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 =
' <пусто> ';
Давайте
снабдим героя в начале игры двумя предметами - легкой броней и недорогим
топором.
Источник: Delgame.at.ua
|