Рассылка закрыта
При закрытии подписчики были переданы в рассылку "Особенности национального бизнеса" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
← Декабрь 2005 → | ||||||
1
|
2
|
3
|
4
|
|||
---|---|---|---|---|---|---|
5
|
7
|
8
|
9
|
10
|
11
|
|
12
|
14
|
15
|
16
|
17
|
18
|
|
19
|
20
|
21
|
23
|
24
|
25
|
|
26
|
28
|
29
|
30
|
31
|
Статистика
0 за неделю
Создание ролевой компьютерной игры 23) Готовимся к стрельбе из лука
Разработка ролевой игры84) Готовимся к стрельбе из лука
procedure IncXP( var H: THero; axp: Integer ); Когда превышен максимальный уровень экспы (опыта), увеличиваем уровень (если он уже не максимально возможный), а на его основе пересчитываем следующий порог опыта, а также новый, повышенный порог здоровья. Информацию о герое мы будем выводить с помощью процедуры ShowHeroFullInfo, которую разместим, конечно в модуле LowLevel, так как это задача, непосредственно связанная с пользовательским интерфейсом.
procedure ShowHeroFullInfo(HeroNum: Integer);
end; Работать она будет так - сперва мы очистим экран покажем все нужные и важные сведения по текущему герою, а затем восстановим полную карту с помощью известной функции:
procedure ShowHeroFullInfo;
ReadLn; ПО какой клавише будем вызывать ее? Допустим, по нажатию на символ 'c', для чего дополним главный цикл обработки событий в модуле Main еще одним пунктом:
...
' c ' : ShowHeroFullInfo;
' g ' : GetItemFromMap; По герою мы желаем знать, прежде всего, значения всех его базовых параметров и навыков, а также сведения по здоровью и опыту, уровень и другие дополнительные сведения. Сначала в цикле покажем параметры из массива Chars и навыки из Skills (для отображения слотов и несомых предметов у нас уже есть процедуры ShowHeroSlots и ShowHeroItems). Для этого, видимо, нам придется подготовить в модуле Texts массив текстовых констант, описывающий название каждого параметра и каждого навыка (в соответствии с порядоком, заданным константами chr..., skill... в модуле Hero).Здесь мы вновь столкнемся с проблемой, уже знакомой нам ранее по подготовке массива SlotName с названиями слотов - из-за того, что мы не можем ссылаться из интерфейсной части одного модуля на интерфейсную часть другого, а в инструкции подключаемых модулей модуля Hero уже указан модуль Texts, описание констант MaxChars и MaxSkills надо будет перенести в модуль Texts, непосредственно к массивам с названиями соответствующих особенностей героя:
MaxChars = 6;
MaxSkills = 3; В модуле Hero раздел констант немного сократится:
const chrSTR = 1;
skillHandWeapon = 1; При этом компилятор нам дополнительно сообщит, что в модуле Tables теперь не определена константа MaxSkills, и поэтому в заголовок надо добавить ссылку и на Texts - новое место этой константы:
unit Tables;
interface uses Hero, Texts;
... Теперь нам осталось удостовериться в правильности этих действий, для чего продолжим процедуру отображения статистик выводом значения навыков:
procedure ShowHeroFullInfo;
for i := 1 to MaxChars do
WriteLn; WriteLn(STR_HEROFI2);
ReadLn; Здесь использована две константы (модуль Texts):
STR_HEROFI = ' Параметры героя: ' ; Что еще будет нас интересовать? Это, без сомнения, уровень героя, текущий набранный опыт и остаток до следующего уровня. Эти данные уже хранятся в структуре THero, поэтому итоговый вариант процедуры, не нуждающийся в комментариях, запишется так:
procedure ShowHeroFullInfo;
WriteLn(STR_HEROFI);
WriteLn; WriteLn(STR_HEROFI2);
ReadLn; Стрельба из лука Следующим шагом по улучшению нашей игры станет реализация дальнобойного оружия. Такое оружие позволит герою вести огонь по противнику с расстояния, однако такая возможность давала бы персонажу слишком большие преимущества перед монстрами, которые бьются только в рукопашную, поэтому на стрельбу нам придется наложить определенные ограничения. Какими они могут быть? Для стрельбы нужны патроны, стрелы, камни, - другими словами, боеприпасы. Для этого нам потребуется два новых типа предметов, назовем их itemAmmo (боеприпасы) и itemRangedWeapon (дальнобойное оружие):
type TGameItemType = (itemHandWeapon, itemArmor, (модуль GameItem). Мы делали наш код таким, чтобы дополнение тех или иных понятий новыми сущностями вызывало какие-то минимальные сообщения об отсутствии их реализации автоматически. Так, если теперь, добавив две новые константы в описание типа TGameItemType, мы попробуем скомпилировать программу, то сразу получим сообщение об ошибке. В модуле LowLevel имеется массив констант ItemRecords, содержащих символы-представления соответствующих предметов. Расширим его двумя новыми позициями. Пусть боеприпасы рисуются символом '|', а дальнобойное оружие (лук) - символом '}'.
const ItemRecords: array[TGameItemType] of TTileRecord = Предметы у нас разбрасываются по карте равномерно и автоматически, так что в нашем виртуальном мире сразу можно будет найти и стрелы, и луки. Сами описания предметов добавляются в массив ItemTypes. Прежде всего увеличим на два значение константы MaxItemTypes - до 6: const MaxItemTypes = 6; а следом - сам массив:
ItemTypes: array[1..MaxItemTypes] of TGameItem =
(ID:5; КОнстанты в модуле Texts описывают название новых типов предметов:
STR_AMMO = ' Стрелы ' ; Условимся, что для боеприпасов первый элемент вложенного массива Ints будет означать число стрел в пакете, а для луков также первый элемент покажет число накопленных для него стрел. Для этого, как мы раньше делали, опишем две константы-индекса соответствующих позиций в этих массивах:
const Взятие лука с земли и перемещение его из инвентаря в руки будет происходить так же, как и с другими вещами. Возможность перемещения в руки у нас задается специально для этого предназначенной функцией GoodSlot (модуль Hero). Нам только надо дополнить список типов предметов, которые можно держать в руках, новым типом дальнобойного оружия:
function GoodSlot(Slot: Integer; Itm: TGameItem): Boolean;
slotBody : GoodSlot := Itm.IType in [itemArmor];
slotHands: GoodSlot := Itm.IType in [itemHandWeapon,
end; Кроме того, если мы выбрали в качестве класса героя стрелка, желательно, чтобы он исходно уже был экипирован не топором, а луком. Пока единый способ размещения топора и бронежилета у нас происходит в процедуре InitHero, но трогать ее мы не будем, а сразу перейдем к новой процедуре генерации героя, где после выбора класса уточним предметы, выдаваемые лучнику. Позже аналогичные манипуляции мы произведем и для мага. Пока же добавим в конец процедуры GenerateHero следующий код:
...
if Heroes[CurHero].Class = classRanger then
end; Здесь мы перезаписываем уже размещенный первым топор на лук (6-й в массиве типов предметов). Кроме того, этому луку мы придаем 10 стрел, используя константу intRangedAmmo. С перемещением из инвентаря "в руки" боеприпасов придется поступить по другому. Нам потребуется дополнительно проверить, находится ли в руках дальнобойное оружие, после чего загрузить в него нужное количество стрел, а сам предмет удалить. В перспективе вероятна необходимость дополнительного анализа соответствия типа боеприпасов типу оружия - ведь из пращи нельзя стрелять стрелами, а стрелы для легкого лука, возможно, будут отличаться от стрел к тяжелому арбалету. Вводя данную дополнительную возможность в игру, мы рано или поздно столкнемся с необходимостью отображения более подробной информации о предметах, хранимых в инвентаре или несомых на теле. Пока для этого мы просто выводим название предмета, однако уже сейчас ясна необходимость как минимум отображения числа стрел для двух новых типов предметов. Поэтому в модуле GameItem мы добавим функцию, которая будет выдавать полное текстовое описание предмета. В ней будут собраны все сведения о всех предметах, и в интерфейсных процедурах наподобие ShowHeroItems достаточно будет внести обращения к такой универсальной функции генерации описания.
function GetItemName(Itm: TGameItem): string;
itemAmmo: GetItemName := Itm.Name +
itemRangedWeapon:
else GetItemName := Itm.Name Не забудем добавить заголовок функции в раздел интерфейса, а в раздел реализации подключим модуль LowLevelдля доступа к функции IntToStr. Теперь следом за названием оружия программа будет сообщать число стрел, в круглых скобочках. Обращение к данной функции разместим в процедурах работы с инвентарем и экипировкой, вместо простых старых выводов названий предметов напрямую. В процедуре ShowHeroSlots:
... В процедуре ShowHeroItems:
... После того, как лук находится в руках, и для него приготовлены стрелы, герой должен научиться стрелять из него и поражать противника на расстоянии. Далее - обучаем меткости и силе стрельбы. Исходный код текущей версии (всегда проверен и работоспособен, главный файл - main.pas): http://russianenterprisesolutions.com/sbo/download/27125.zip 11295 байта (c) 2004-2005 Сергей Бобровский bobrovsky@russianenterprisesolutions.com
Школа программирования с нуля
Дизайн рассылки: Алексей Голубев - Web-дизайн и web-программирование |
Subscribe.Ru
Поддержка подписчиков Другие рассылки этой тематики Другие рассылки этого автора |
Подписан адрес:
Код этой рассылки: comp.soft.prog.prognull.game Архив рассылки |
Отписаться
Вебом
Почтой
Вспомнить пароль |
В избранное | ||