При закрытии подписчики были переданы в рассылку "Особенности национального бизнеса" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
Информационный Канал Subscribe.Ru |
Разработка ролевой игры18) Монстры наносят ответный ударнашел электронную (пиратскую, конечно :) свою книгу.
"Самоучитель прграммирования на языке C++ в системе Borland C++ Builder 4.0"
Мало того, что сайт тормозной, так автор сайта, еще, видимо, такой чайник, что не смог даже набрать название системы грамотно :) Dorland - проверю в яндексе... Надо же, 2205 страниц!
Хм, ну пусть с пиратом боевики издателя разбираются. Ух! Очень свирепые ребята.
Монстры наносят ответный удар Что происходит с монстром, когда он все же получил повреждение? Его здоровье понижается, а в случае, когда оно становится меньше или равным нулю, считается, что монстр погиб, а вот герой получит причитающийся ему за победу опыт:
procedure HeroAttack( var H: THero; m: Integer );
i := GetHeroWeapon(H);
dam := WeaponDamage( H.Slots[i] );
dec( Monsters[m].HP, dam-skin );
if Monsters[m].HP <= 0 then
end; Текстовые константы могут быть описаны в модуле Texts так:
const STR_ATTACK = ' Герой наносит повреждение ' ; Попробуйте походить по локации, нападая на встречающихся монстров. После перерисовки карты погибший монстр исчезнет с нее автоматически. Пока сражения окажутся несложными - ведь чудовища пока не умеют давать сдачи. Монстры наносят ответный удар Где будет находится процедура ответных ударов окружающих героя монстров? Она будет вызываться сразу после процедуры HeroAttack. Назовем ее MonstersAttack:
procedure MoveHero( dx,dy: Integer );
m := IsMonsterOnTile(Heroes[CurHero].x+dx, Heroes[CurHero].y+dy); Отметим, что в этой процедуре мы не ограничимся ответным ударом одного атакованного монстра. Ведь, хотя наш положительный персонаж один, нападающих на него монстров может быть много, и каждый из них имеет право на свою атаку. При этом в свою очередь хода герой может напасть только на одного монстра, точно также, как и его противники. Каждый из них имеет право ровно на одну атаку, но ведь их несколько! Поэтому персонажу периодически придется после одного нападения отражать несколько вражеских атак. Реализуем процедуру MonstersAttack в модуле Combat.
procedure MonstersAttack;
end; Проверим каждого монстра - жив ли он и здоров, а также находится ли герой в зоне досягаемости этого монстра. Последнюю проверку вынесем в отельную функцию, котором поместим в этот же модуль. Параметрами ее выступают индекс персонажа в массиве Heroes и индекс монстра в массиве Monsters:
function CanAttack(mi, hi: Integer): Boolean; Досягаемость выясняется просто - достаточно проверить, находится ли монстр на расстоянии одной клетки от персонажа. Расстояние между объектами локации измеряется, напомним, только по вертикали и горизонтали. Это расстояние можно вычислить с помощью функции Distance:
function Distance(xf,yf, xt,yt: Integer): Integer; После того, как определен монстр, способный напасть на героя, выполняется непосредственный расчет его атаки. Эта атака может быть запрограммирована так:
procedure MonsterAttack(m: Integer; var H: THero );
dam := RollDice( Monsters[m].Ad1, Monsters[m].Ad2 );
ShowInfo(Monsters[m].Name + STR_MON_ATTACK); Этот текст требует пояснений. Вначале происходит проверка умения героя уклоняться от ударов. Пока у нас умения skillDefence нет. Поэтому выполним процедуру добавления нового навыка. Делается это так. В модуле Hero увеличиваем значение константы MaxSkills до 3, и вводим новую константу skillDefence:
const MaxSkills = 3; Теперь при попытке компиляции программы возникнет ошибка в модуле Tables - ведь мы изменили длину массива BaseSkill_Table, в котором хранятся базовые значения навыков. Давайте дополним его новым значением:
const BaseSkill_Table: array[1..MaxSkills] of Integer = Величина 25% для защиты выглядит не очень высокой. Она означает, что герой сможет отбивать каждый четвертый удар. Однако далее мы сделаем так, чтобы со временем этот процент быстро рос - до разумных значений, конечно. Далее исправим процедуру SkillTest:
function SkillTest( var H: THero; skl: Integer ): Boolean;
case skl of
skillHandWeapon,
skillTrapSearch:
end; Здесь проверки навыков, не требующих дополнительных действий, объединены в один обработчик. А рост навыка обороны добавим в процедуру SuccessSkillTest. Как часто нам надо будет повышать этот навык? Вспомним аналогичные подсчеты, связанные с умением наносить удары (skillHandWeapon). За игру персонаж, как мы подсчитали, может атаковать монстров около двух тысяч раз. Количество ответных нападений монстров будет, конечно, большим. Ведь для героя мы считали только успешные атаки, а обороняться ему придется от всех нападений противника. Поэтому выберем приближенное значение - например, пять тысяч. Пусть навык возрастет с 25 до 75%. Большее, чем 75, значение брать неразумно - ведь тогда герой станет слишком неуязвимым и способным отражать все без исключения атаки противника. Теперь мы можем рассчитать вероятность повышения этого навыка на единицу - она будет равна 5000 / (75 - 25) или такое повышение должно происходить в одном случае из ста.
procedure SuccessSkillTest( var H: THero; skl: Integer);
skillDefence:
... После того, как выяснено, что герою не удалось уклониться от нападения, выполняется вычисление величины поражения, которое наносит монстр. Эта величина зависит от соответствующих характеристик монстра (поля Ad1, Ad2). Наконец, вычисляется бронезащита персонажа (величина, аналогичная шкуре монстра). Такая бронезащита непосредственно связана с количеством надетой на героя брони. Расчет данного параметра происходит в функции GetHeroDefence:
function GetHeroDefence( var H: THero ): Integer; Выполняющиеся здесь действия вполне можно было вынести в один оператор, но мы умышленно обобщили структуру функции с учетом того, что число слотов, связанных с броней, может быть в будущем увеличено. Если в дальнейшем в программу будет добавлен новый слот для шлема, то данную процедуру надо видоизменить следующим образом:
function GetHeroDefence( var H: THero ): Integer; Константу добавим, для слота шлема:
const slotBody = 1; И ее описание, в модуле Texts:
const MaxSlots = 3; В заключение в MonsterAttack происходит снижение уровня здоровья героя - при попадании. Константы в упомянутых процедурах выглядят так:
const STR_DEFENCESKILL_OK = ' Вы отбили удар! ' ;
Исходный код текущей версии (всегда проверен и работоспособен, главный файл- main.pas): http://russianenterprisesolutions.com/sbo/download/22115.zip 9348 байтов Далее - Монстры бросаются в погоню. (c) 2004-2005 Сергей Бобровский bobrovsky@russianenterprisesolutions.com
Школа программирования с нуля
Дизайн рассылки: Алексей Голубев - Web-дизайн и web-программирование |
Subscribe.Ru
Поддержка подписчиков Другие рассылки этой тематики Другие рассылки этого автора |
Подписан адрес:
Код этой рассылки: comp.soft.prog.prognull.game Архив рассылки |
Отписаться
Вспомнить пароль |
В избранное | ||