При закрытии подписчики были переданы в рассылку "Особенности национального бизнеса" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
Информационный Канал Subscribe.Ru |
Разработка ролевой игры15) Рюкзак и инвентарь-2
procedure InitHero(HeroNum: Integer);
with Heroes[HeroNum] do Первым и вторым предметами, хранящимися в рюкзаке героя, стали топор и броня. Эти предметы в дальнейшем нам надо будет перемещать из рюкзака на тело и в руки героя ("надевать"). Для этого нам также потребуется еще один массив, который мы назовем Slots, элементы которого будут соответствовать предметам, непосредственно используемым героем. Это может быть броня или оружие. В коммерческих играх список носимых предметов обычно расширяется амулетами, кольцами, цепочками, колчаном, оружейным поясом, отдельными элементами брони для рук (наручи), ног (поножи), специализированными видами оружия и т. д. Читатель может самостоятельно реализовать в игре такую возможность по описанной далее схеме. Опишем массив Slots в структуре THero:
const MaxSlots = 2;
type THero = record Пока мы отвели герою два слота (броня на теле и оружие в руках), доступ к которым может происходить с помощью индексов slotBody и slotHands. Проинициализируем этот массив в процедуре InitHero:
procedure InitHero(HeroNum: Integer);
with Heroes[HeroNum] do Как и в случае с рюкзаком, массив слотов просто представим набором "пустых" предметов. Для отображения носимых героем предметов подготовим процедуру ShowHeroSlots (модуль LowLevel):
procedure ShowHeroSlots; Константа STR_HERO_SLOTITEMS должна быть описана в модуле Texts:
const STR_HERO_SLOTITEMS = ' Используемые героем предметы: ' ; Массив констант SlotName (названия слотов героя) опишем также в модуле Texts:
const SlotName: array[1..MaxSlots] of string[20] = Внесение этой константы в программу может вызвать определенные трудности. Дело в том, что она использует другую константу - MaxSlots, которая описана в модуле Hero. Попытка добавить ссылку на модуль Hero в interface-заголовок модуля Texts закончится неудачно из-за того, что возникает замкнутая кольцевая цепочка ссылок interface-разделов друг на друга. Модуль Texts ссылается на модуль Hero, а тот в свою очередь - на модуль GameItem, которому снова требуется сслыка на Texts, так как в его интерфейсной части расположены описания массива типовых предметов ItemTypes, поле Name которого требует указания константы из модуля Texts. Сейчас мы решим эту проблему "в лоб". Переместим описание константы MaxSlots, из-за которой разгорелся весь сыр-бор, в модуль Texts (хотя это и не совсем корректно в смысловом плане):
const MaxSlots = 2; Добавим в список подключенных модулей модуля Hero ссылку на модуль Texts, чтобы оставалась доступной константа MaxSlots:
unit Hero;
interface uses GameItem, Texts; одновременно убрав ее из раздела реализации. Теперь программа соберется без проблем. Однако, как уже говорилось, такой подход, хотя и достигает цели, но все же не может считаться оптимальным. Ведь модуль Texts предназначен для хранения только текстовых констант, и подобное смешение понятий может по мере усложнения программы привести к новым ошибкам подобного класса. Правильнее спрятать подробное описание массива ItemTypes в раздел реализации модуля GameItem, переместив туда же и ссылку на модуль Texts, а доступ к элементам ItemTypes обеспечить с помощью дополнительной функции - например, GetItemType, возвращающей элемент массива по его номеру (параметру функции). Вы сами можете дополнить программу такой возможностью. Вызов процедуры ShowHeroSlots введем в обработчик нажатий на клавиши в главном модуле программы Main. Пусть список надетых героем предметов показывается при нажатии на клавишу 'e':
while true do
' e ' : ShowHeroSlots;
' i ' : ShowHeroItems;
Вызываемые функции расположены в алфавитном порядке нажимаемых клавиш - это удобно, так как позволяет быстро найти нужный обработчик определенного нажатия. Предметы, хранящиеся в рюкзаке, и надетые на тело, надо уметь менять местами (из рук убрать в рюкзак, а из рюкзака - одеть на тело). Кроме того, предметы иногда приходится выбрасывать на землю и поднимать с земли. Разделим эту задачу на несколько частей. Носимые предметы - в рюкзак Расширим экран списка надетых предметов дополнительными возможностями. Позволим человеку отдавать команды - например, ввод номера слота будет означать команду "предмет из слота N убрать в рюкзак". Для этого в процедуре ShowHeroSlots добавим возможность ввода номера, а также выделим основную часть процедуры в бесконечный цикл, который будет прекращаться, когда пользователь введет в качестве номера ноль.
procedure ShowHeroSlots;
while true do
ShowGame; Введенное значение надо проверить. Если слот пуст, или в рюкзаке нет места, никаких действий предпринимать не надо. В противном случае (в слоте есть предмет и в рюкзаке есть свободные места) переместим предмет в рюкзак. Проверка пустоты слота несложна, а вот поиск свободного места в рюкзаке желательно реализовать в виде отдельной функции. Дело в том, что данная реализация будет в значительной степени зависеть от способа определения свободного места в рюкзаке. Этот способ может содержать анализ веса несомого груза, поиск местоположения предмета в рюкзаке и так далее. Поэтому выделим его в функцию GetFreeBag, возвращающую номер свободного элемента в рюкзаке или ноль в случае неудачи. Запишем функцию в модуле Hero:
function GetFreeBag( var H: Thero ): Integer; В ней происходит перебор предметов, хранящихся в рюкзаке, и как только обнаруживается элемент, у которого значение поля IType соответствует значению типа "пустого" предмета, функция возвращает его индекс в массиве Items, входящего в структуру Hero. С учетом этих нововведений процедура ShowHeroSlots запишется так:
procedure ShowHeroSlots;
while true do
s := GetFreeBag(Heroes[CurHero]);
end;
ShowGame; После того, как введенный номер слота проверен и выяснено, что он корректен, скопируем соответствующий элемент массива Slots в найденный незанятый элемент рюкзака (массив Items), после чего пометим элемент Slots[n] как "пустой". Исходный код текущей версии (всегда проверен и работоспособен, главный файл- main.pas): http://russianenterprisesolutions.com/sbo/download/1115.zip 7299 байтов Далее: Одеваем предметы из рюкзака. (c) 2004-2005 Сергей Бобровский bobrovsky@russianenterprisesolutions.com
Школа программирования с нуля
Дизайн рассылки: Алексей Голубев - Web-дизайн и web-программирование |
Subscribe.Ru
Поддержка подписчиков Другие рассылки этой тематики Другие рассылки этого автора |
Подписан адрес:
Код этой рассылки: comp.soft.prog.prognull.game Архив рассылки |
Отписаться
Вспомнить пароль |
В избранное | ||