Создание ролевой компьютерной игры 55) Работа с инвентарем
Школа программирования
55) Программирование ролевой игры: Работа с инвентарем
Работа с инвентарем должна выполняться в отдельной форме, на которой расположим список и две кнопки "Использовать" и "Бросить". А поле-метка MoneyLabel будет ответственно за отображение текущей наличности. Тем самым мы полностью дублируем задачу, решаемую DOS-версией кода.
Создадим новую форму, назовем ее InvForm. Разместим на ней список и назовем его ListBox. Добавим также метку MoneyLabel для вывода текущей суммы денег, кнопку UseButton с заголовком "Использовать", по нажатию на которую будет взят элемент из инвентаря, кнопку DropButton с заголовком "Бросить".
Все действия по работе с инвентарем "погрузим" в код этой формы. Одно из действий, которое наверняка будет требоваться многократно - это формирование списка предметов и вывод текущей суммы наличности. Назовем такой метод - ShowItemList:
// ----- procedure TInvForm.ShowItemList; var fg,i,n,s: Integer; begin
ListBox.Clear; for i := 1 to MaxHeroItems do begin if Heroes[CurHero].Items[i].IType = itemNone then ListBox.Items.Add(STR_EMPTY_ITEM) else ListBox.Items.Add( GetItemName(Heroes[CurHero].Items[i]) ) end;
i := GetMoneyNo(Heroes[CurHero]); if i > 0 then MoneyLabel.Caption :=
IntToStr(Heroes[CurHero].Items[i].Ints[intMoney])+ ' $ ' else MoneyLabel.Caption := ' 0 ' ; end; //
Из текущей процедуры будем лишь вызвать форму к отображению (после подготовки списка инвентаря):
{ ----------------- } procedure ShowHeroItems; begin
InvForm.ShowItemList;
InvForm.ShowModal; end;
Процедура использования предмета почти не отличается от DOS-версии:
// ----- procedure TInvForm.UseButtonClick(Sender: TObject); var fg,i,n,s: Integer; begin
n := ListBox.ItemIndex+1;
if Heroes[CurHero].Items[n].IType = itemAmmo then begin if Heroes[CurHero].Slots[slotHands].IType = itemRangedWeapon then begin
Heroes[CurHero].Slots[slotHands].Ints[intRangedAmmo] :=
Heroes[CurHero].Slots[slotHands].Ints[intRangedAmmo] +
Heroes[CurHero].Items[n].Ints[intAmmo];
Heroes[CurHero].Items[n].IType := itemNone;
ShowItemList; end end else
if Heroes[CurHero].Items[n].IType = itemEat then begin
fg := Heroes[CurHero].Fatigue;
fg := round( fg * (95-random(21))/100 );
Heroes[CurHero].Fatigue := fg;
Heroes[CurHero].Items[n].IType := itemNone;
ShowItemList;
ShowInfo(STR_FATGOOD + IntToStr(fg)); end else
if not UseMagikItem(n) then begin
s := GetFreeSlot(Heroes[CurHero],Heroes[CurHero].Items[n]); if s > 0 then begin
Heroes[CurHero].Slots[s] := Heroes[CurHero].Items[n];
Heroes[CurHero].Items[n].IType := itemNone;
ShowItemList; end; end;
end; //
Схожа ситуация и с кодом избавления от предмета:
// ----- procedure TInvForm.DropButtonClick(Sender: TObject); var n,s: Integer; begin
s := GetFreeItemNum;
n := ListBox.ItemIndex+1; if s > 0 then begin
Items[s] := Heroes[CurHero].Items[abs(n)];
Items[s].x := Heroes[CurHero].x;
Items[s].y := Heroes[CurHero].y;
Heroes[CurHero].Items[abs(n)].IType := itemNone;
ShowItemList; end; end; //
Подобный подход, с созданием отдельной формы, применим и к подпрограмме отображения содержимого слотов персонажа (что на нем одето и что у него в руках). Создадим новую форму и назовем ее SlotForm. Разместим на этой форме список ListBox и кнопку InvButton ("В инвентарь").
Создадим в ней процедуру заполнения списка обмундирования:
// ----- procedure TSlotForm.ShowItemList; var i: Integer; begin
ListBox.Clear; for i := 1 to MaxSlots do begin if Heroes[CurHero].Slots[i].IType = itemNone then ListBox.Items.Add(STR_EMPTY_ITEM) else ListBox.Items.Add( GetItemName(Heroes[CurHero].Slots[i])) end;
ListBox.ItemIndex := 0; end; //
Добавим обработчик нажатия на кнопку "В инвентарь":
// ----- procedure TSlotForm.InvButtonClick(Sender: TObject); var s,n: Integer; begin
n := ListBox.ItemIndex+1;
s := GetFreeBag(Heroes[CurHero]); if (Heroes[CurHero].Slots[n].IType <> itemNone) and (s > 0) then begin
Heroes[CurHero].Items[s] := Heroes[CurHero].Slots[n];
Heroes[CurHero].Slots[n].IType := itemNone;
ShowItemList; end; end; //
Вызов самой формы вставим в процедуру ShowHeroItems:
{ ----------------- } procedure ShowHeroItems; begin
InvForm.ShowItemList;
InvForm.ShowModal; end;
Код процедуры ShowHeroFullInfo также будет связан с новой формой - назовем ее FullInfoForm. Но так как интерактивных элементов в нем нету - лишь выводятся сведения о персонаже, достаточно разместить текстовое поле Memo с выключенным режимом редактирования, и кнопку закрытия. А заносить информацию будем непосредственно в модуле LowLevel.
{ ----------------- } procedure ShowHeroFullInfo; var i: Integer; begin
with FullInfoForm do begin
Memo.Clear;
Memo.Lines.Add(Heroes[CurHero].Name+ ' , ' +
RaceName[Heroes[CurHero].Race]+ ' ' +
ClassName[Heroes[CurHero].HeroClass]);
Memo.Lines.Add(STR_HEROFI_LEVEL+ IntToStr(Heroes[CurHero].Level));
Memo.Lines.Add(STR_MAPFI_LEVEL+ IntToStr(CurMap));
Memo.Lines.Add(STR_HEROFI_EXP+ IntToStr(Heroes[CurHero].Exp)+ ' /
' +IntToStr(Heroes[CurHero].MaxExp));
Memo.Lines.Add(STR_HEROFI_FAT+ IntToStr(Heroes[CurHero].Fatigue)+ '
/ ' +IntToStr(MAX_FATIGUE));
Memo.Lines.Add( ' ' ); for i := 1 to MaxChars do
Memo.Lines.Add( CharsName[i]+ ' : ' + IntToStr(Heroes[CurHero].Chars[i]) );
Memo.Lines.Add( ' ' ); for i := 1 to MaxSkills do
Memo.Lines.Add( SkillsName[i]+ ' : ' + IntToStr(Heroes[CurHero].Skills[i]) );
ShowModal; end; end;
Потребует реализации на базе новой формы и функция GetSpellNo - в ней надо выбрать заклинание для использования. Создадим новую форму SpellForm, управлять действием будем двумя стандартными кнопками - OK при запуске выбранного заклинания и Cancel при отказе. Добавим на форму список ListBox.
Модификация списка заклинаний у нас не выполняется - пользователь должен лишь выбрать заклинание и нажать кнопку OK, поэтому создавать специальную процедуру формирования такого списка не будем, так как он всегда одинаков. Поэтому весь код обработки можно оставить в модуле LowLevel.
{ ----------------- } function GetSpellNo: Integer; var i: Integer; begin
SpellForm.ListBox.Clear;
for i := 1 to MaxSpells do
SpellForm.ListBox.Items.Add(Spells[i].Name+ ' : ' +IntToStr(Spells[i].Mana));
SpellForm.ListBox.ItemIndex := 0;
if SpellForm.ShowModal = mrOk then GetSpellNo:=SpellForm.ListBox.ItemIndex+1 else GetSpellNo:=0;
end;
Теперь, после написания данного кода, у нас в Windows сразу стал работоспособен очередной режим игры - за магов.