S***********
Я хочу шаг за шагом создать простой текстовый "файтинг", без графики и наворотов. Главное - концепт и устройство игры, чтобы те, кто совсем не понимает в этом, могли бы хотя бы немного узнать, как это делается.
Я сам очень плохо программирую, гораздо больше читал о геймдевелопинге - но на этом примитивном примере мы сможем очень многое понять.
В качестве языкы программирования я выбрал ADA, язык схожий на очень простой Паскаль, который используется в учебных целях. От иного языка я отказываюсь по причине того, что их синтакс не очень лёгок для понимания.
В качестве основы, я возьму некое подобие правил Dungeons & Dragons. Т.е. важную роль играют статистика персонажа и кубики.
"Кубики" понятие абстрактное в этой игре. Это всего лишь генераторы чисел в определённом диапазоне, добавляюшие в игру случайность, но чем выше характеристики персонажа, тем меньше шансов у случайности вам насолить. Ваша задача всегда попасть с помощью кубика и вашей характеристики в определённый диапазон чисел.
Следующие виды "кубиков" используются в игре:
Д2, Д3, Д4, Д8, Д10, Д20, Д100.
Д от Dice (Кубик по английски), второе число указывает верхнюю границу диапазона. Т.е. Д20 генерирует число от 1 до 20.
Итак.
Идея
Экран делится на две части - слева описание главного героя, его статистика, справа вашего врага.
Внизу, с помощью цифр мы выбираем действия, как то: сражаться, заходить в магазин или использовать предмет.
Каждый герой обладает типичными для ролевой игры характеристиками:
Name - Имя
Level - уровень
HP - очки жизни
MP - очки маны
Strength - сила, определяет дополнительный урон
Dexterity - ловкость, определяет уровень брони
Constitution - определяет уровень очков жизни
Speed - влияет на очерёдность ходов
Luck - влияет на такие фишки как "критический удар" и "Избежание удара"
Experience - определяет уровень
Gold - куда же без них, денег то.
Перед боем мы имеем возможность:
1)начать бой
2)зайти в магазин
3)настроить игрока (если поднялся уровень)
В магазине можно купить напиток или вооружение.
После того как начинается бой, сначала определяется очерёдность.
Оба героя кидают Д20+модификатор от Speed (Скорости). У кого больше в итоге - тот ходит первым.
Модификатор - это определённое число, высчитываемое их характеристики. Например если Strength=10, то модификатор равен 0, если 12 или 13, то +1, 14 или 15, то +2 и т.д.
Атака:
1)герой должен сначала пробить броню противника.
Броня противника - 10 + модификатор от Dexterity + Бонус от текущей брони/доспехов
Герой бросает Д20+модификатор ловкости
Если ему удаётся перейти уровень брони противника, то засчитывается урон (от текущего оружия, например Д4).
Когда один из бойцов теряет все очки жизни, второй получает его опыт и золото.
Как только опыт достигает 100 пунктов, происходит повышение уровня.
Во время боя можно атаковать, использовать предмет или магию или сбегать.
После смерти главного героя, у него отбирается часть опыта и денег.
Вот такая вот структура игры.
Теперь определим порядок
1)показываем главный экран с выбором действий (начать битву, магазин, поднять уровень, инвентарь)
если выбирается "начать битву" то
2)переходим на экран с "битвой" с выбором (атаковать, использовать предмет, магия, бежать) и затем устанавливается
а)очерёдность бойцов
б)если игрок начинает атаку, то он пытается пробить броню и нанести урон. после удачи или неудачи ход заканчивается
в)если игрок теряет все жизни, то возвращается на экран 1) и получает пенальти. Устанавливается следующий враг.
г)если противник теряет все жизни, то игрок возвращается на экран 1) и получает бонусы.Устанавливается следующий враг.
д)если игрок использует предмет, то теряет ход
е)если игрок использует магию, то переходит на экран выбора заклинания и проводит свой удар. ход заканчивается
ж)если игрок убегает, то переходит на экран 1) и получает пенальти. Устанавливается следующий враг.
3)игрок заходит в магазин и может выбрать из (напитки, оружие, броня).
выбрав "напитки" он может купить напитки
выбрав "оружие" он может купить оружие
выбрав "броня" он может купить броню
4)зайдя "инвентарь" игрок может посмотреть текущие характеристики вооружения и брони.
Вот так вот примитивно мы описали игру.
Переходим к реализации.
Программа состоит из одной главной процедуры (или просто процесса, который стоит выше всех). В нем будут распологаться многие более мелкие процедуры, каждая из которых отвечает за некоторое действие.
Рассмотрим к примеру одну маленькую процедуру:
procedure LEVEL_UP (HERO1 : in out HERO) is
begin
PUT_LINE("***Level up!***");
HERO1.LVL:=HERO1.LVL+1;
HERO1.EXP:=0;
end LEVEL_UP;
Это упрощённая процедура повышения уровня персонажа. Причем не конкретного, а того, которого вы укажете в скобках после названия. Если вы победили, то ваш герой попадёт в скобки, если враг - то он.
Рассмотрим детально процедуру.
procedure LEVEL_UP (HERO1 : in out HERO) is
название процедуры и в скобках т.н. аргумент. Если мы хотим поднять уровень вашему персонажу, то в качестве аргумента мы впишем где-то в коде игры "LEVEL_UP(Link);". Это проведёт над Link описаные в процедуре действия.
begin
говорит о начале кода процедуры
PUT_LINE("***Level up!***");
выводит сообщение о том, что уровень игрока поднят
HERO1.LVL:=HERO1.LVL+1;
каждый объект, будь то бутылка или герой обладают характеристиками. Они следуют за именем объекта. Здесь Hero1 имеет характеристику LVL (Level), т.е. уровень персонажа. В этой строчке мы прибавляем к уровню персонажа единичку
HERO1.EXP:=0;
здесь мы обнуляем уровень опыта до нуля, чтобы можно было далее набирать его
end LEVEL_UP;
процедура заканчивается.
Эта самая процедура должна теперь где-то в коде быть упомянута. Представьте себе следующую ситуацию.
Идёт бой, противник теряет все очки жизни, вам перечисляется опыт. Теперь, игра спрашивает себя "а что если количество очков персонажа стало больше 100?". И дальше "если это так, то сделаем ка мы повышение уровня для этого персонажа: level_up(персонаж); если нет - то ничего не делаем).
Теперь более ближе к коду:
Битва продалжается до Победы или Поражения
игрок наносит удар
ЕСЛИ противник.жизнь <= 0 то Победа
ИНАЧЕ противник наносит удар
ЕСЛИ игрок.жизнь <= 0 то Поражение
ИНАЧЕ продолжай сначала
ЕСЛИ Победа то игрок1.опыт=игрок1.опыт+противник.опыт; (вы получаете опыт противника в случае Победы)
ИНАЧЕ игрок1.опыт:=игрок1.опыт - противник.опыт; противник.опыт:=противник.опыт+игрок.опыт; (противник получает ваш опыт в случае Поражения)
ЕСЛИ игрок.опыт > 100 ТО LEVEL_UP(игрок)
Вот так вот мы подняли опыт игроку.
Теперь вернёмся к характеристикам. Как уже говорилось, каждый объект в игре (игрок, враг, доспех, бутылка) имеют некие характеристики. Эти характеристики указываются после точки.
Мы могли бы создавать героя или врага в любой момент игры снова, но гораздо удобнее создать один шаблон, и потом просто создавать с него копии и изменять характеристики этих копий.
Шаблоном у нас является "тип".
Мы создаём Тип с названием HERO и после слова record (указывает на то, что тип состоит из многих характеристик) начинаем перечислять характеристики и их вид. Понятно, что текстовое имя должно состоять из букв, а какая-то характеристика типа Силы, должна быть числом.
type HERO is
record
NAM : UNBOUNDED_STRING;
LVL : INTEGER range 1 .. 99;
HP : INTEGER range - 10 .. 1000;
MP : INTEGER range 0 .. 1000;
STR : INTEGER range 0 .. 100;
DEX : INTEGER range 0 .. 100;
CON : INTEGER range 0 .. 100;
SPD : INTEGER range 0 .. 100;
LCK : INTEGER range 0 .. 100;
EXP : INTEGER range 0 .. 100;
GLD : INTEGER;
end record;
Возмьём к примеру строчки
NAM : UNBOUNDED_STRING;
LVL : INTEGER range 1 .. 99;
Все пункты (NAM, LVL, STR, LCK etc.) - это просто сокращения от описаных выше характеристик (Level, Strength и т.д.). Зачем делают сокращения а не пишут целые слова? Потому что так потом быстрее. Можно конечно же было писать и полными словами.
NAM - это будет имя героя, состоит из букв, поэтому в языке программирования ему соотв. тип STRING
LVL - это уровень героя. Уровень, это всегда число. Число указывается через слово Integer, затем я указывают с помощью range 1..99, что уровень может принимать значения от 1 до 99.
Теперь можно создать копию с этого шаблона.
MANSK : HERO;
Mansk был создан по образу и подобию HERO, это значит, что у него все те характеристики, которые заложены в его родителя.
Мы можем в любое время взять их под скальпель. Чтобы начать работу с характеристикой Mansk, надо её вызвать или правильно к ней обратиться, через точку. Mansk.Nam - это имя, а точнее то, что стоит в характеристике nam.
Ну что же, создадим Чапаева
MANSK.NAM:="Василий Иванович Чапаев";
MANSK.LVL:=45;
MANSK.HP:=233;
MASSK.MP:=0;
MANSK.STR:=34;
MANSK.DEX:=19;
MANSK.CON:=40;
MANSK.SPD:=30;
MANSK.LCK:=3;
MANSK.EXP:=23;
MANSK.GLD:=24334;
Вот такой вот у нас герой MANSK по кличке "Василий Иванович Чапаев", с нулевой Маной и низкой удачей (отчего он и утонул в Урале).
Точно также мы можем создавать и других героев и врагов.
Enemy: HERO;
Boss: HERO;
Ally: HERO;
Enemy, Boss и Ally - имеют те же свойства (сила, удача), но мы вольны изменять их значения!
На этом делаем паузу и ждём продолжения....