ТОМ: Уроки: различия между версиями
ASBer (обсуждение | вклад) м (→наименования) |
ASBer (обсуждение | вклад) м (→Урок 5: Дополнительные локации, карта и стороны света) |
||
(не показана 41 промежуточная версия этого же участника) | |||
Строка 9: | Строка 9: | ||
− | + | Итак, у нас есть новый, чистый, только что созданный файл "my_game.tom", открытый в блокноте. | |
Строка 136: | Строка 136: | ||
Как придать индивидуальность объектам игры читайте далее. | Как придать индивидуальность объектам игры читайте далее. | ||
− | ==Урок 3: | + | ==Урок 3: Авторские описания и дополнительные возможности== |
===наименования=== | ===наименования=== | ||
Стандартная библиотека требует обязательно указывать наименования предметов, локаций и персонажей. | Стандартная библиотека требует обязательно указывать наименования предметов, локаций и персонажей. | ||
Строка 146: | Строка 146: | ||
//... | //... | ||
} | } | ||
+ | Здесь: | ||
+ | *пещер%; - основа лексемы. Для образования словоформ вместо % подставляются различные окончания. | ||
+ | *ЖрЕчНдСи; - свойства лексемы: | ||
+ | **Жр - женский род; | ||
+ | **Еч - единственное число; | ||
+ | **Нд - неодушевлённое; | ||
+ | **Си - Существительное имя; | ||
+ | *Ип; - Форма по умолчанию. Если не указано другого согласования, будет применена форма именительного падежа. | ||
+ | *Ип=а; - окончание словоформы для именительного падежа; | ||
+ | *Рп=ы; - для родительного падежа; | ||
+ | *Дп=е; - для дательного падежа; | ||
+ | *Вп=у; - для винительного падежа; | ||
+ | *Тп=ой; - для творительного падежа; | ||
+ | *Тп=ою; - 2е окончание для творительного падежа; | ||
+ | *Пп=е; - окончание для предложного падежа. | ||
Для меча указываем наименование в виде словосочетания. | Для меча указываем наименование в виде словосочетания. | ||
− | Для генерации текстов это вполне подходит, но для парсера надо повторить каждое слово отдельно: | + | Для генерации текстов это вполне подходит, но для парсера надо повторить каждое слово отдельно. |
− | + | Если предмет можно назвать несколькими словами, все синонимы также необходимо добавить: | |
+ | unique меч | ||
{ //... | { //... | ||
наименование = "заколдованн% тесак%; МрЕчНдСи; Ип; Ип=ый,; Рп=ого,а; Дп=ому,у; Вп=ый,; Тп=ым,ом; Пп=ом;е" | наименование = "заколдованн% тесак%; МрЕчНдСи; Ип; Ип=ый,; Рп=ого,а; Дп=ому,у; Вп=ый,; Тп=ым,ом; Пп=ом;е" | ||
this.тесак = "тесак%; МрЕчНдСи; Ип; Ип=; Рп=а; Дп=у; Вп=; Тп=ом; Пп=е" | this.тесак = "тесак%; МрЕчНдСи; Ип; Ип=; Рп=а; Дп=у; Вп=; Тп=ом; Пп=е" | ||
this.заколдованный = "заколдованн%; МрЕчНдПи; Ип; Ип=ый; Рп=ого; Дп=ому; Вп=ый; Тп=ым; Пп=ом" | this.заколдованный = "заколдованн%; МрЕчНдПи; Ип; Ип=ый; Рп=ого; Дп=ому; Вп=ый; Тп=ым; Пп=ом" | ||
+ | this.меч = "меч%; МрЕчНдСи; Ип; Ип=; Рп=а; Дп=у; Вп=; Тп=ом; Пп=е" | ||
//... | //... | ||
} | } | ||
+ | "заколдованн%; МрЕчНдПи; Ип; Ип=ый; Рп=ого; Дп=ому; Вп=ый; Тп=ым; Пп=ом" - здесь в свойствах лексемы | ||
+ | *Мр - мужской род; | ||
+ | *Пи - прилагательное имя. | ||
Строка 164: | Строка 184: | ||
Также для персонажей необходимо указывать звательный падеж - Зп: | Также для персонажей необходимо указывать звательный падеж - Зп: | ||
ГГ.по_имени = "гоблин%; МрЕчОдСи; Ип; Зп=; Ип=; Рп=а; Дп=у; Вп=а; Тп=ом; Пп=е" | ГГ.по_имени = "гоблин%; МрЕчОдСи; Ип; Зп=; Ип=; Рп=а; Дп=у; Вп=а; Тп=ом; Пп=е" | ||
+ | "гоблин%; МрЕчОдСи; Ип; Зп=; Ип=; Рп=а; Дп=у; Вп=а; Тп=ом; Пп=е" - здесь | ||
+ | *Од - одушевлённое; | ||
+ | *Зп=; - пустое окончание для звательного падежа. | ||
− | ''Вместо "наименование" можно писать "title". | + | ====примечания:==== |
− | + | *''Вместо "наименование" можно писать "title". Оба слова являются зарезервированными ключевыми словами интерпретатора и абсолютно равнозначны.'' | |
+ | *''Для лучшего понимания лексем, их согласования и словообразования смотрите темы [[ТОМ: Лексема]] и [[ТОМ: Морфологический ключ]].'' | ||
+ | |||
+ | ===флаги и отношения=== | ||
+ | Для настройки поведения предметов стандартная библиотека предназначает следующие свойства: | ||
+ | *'''можно_взять''' - флаг, по умолчанию "нет" | ||
+ | *'''чей''' - отношение собственности | ||
+ | unique меч | ||
+ | { //... | ||
+ | можно_взять = да | ||
+ | чей = ГГ //принадлежит гоблину | ||
+ | //... | ||
+ | } | ||
===описания=== | ===описания=== | ||
+ | Попробуем заменить стандартные скучные описания своими собственными. | ||
+ | |||
+ | Для авторских описаний объектов стандартная библиотека предназначает следующие свойства: | ||
+ | |||
− | + | для локаций: | |
− | + | *описание | |
+ | *полное_описание | ||
location пещера | location пещера | ||
− | { | + | { //... |
− | |||
полное_описание = "Это пещера, в которой ты прожил большую часть своей жизни. Мебели нет совсем, но где-то здесь ты зарыл клад." | полное_описание = "Это пещера, в которой ты прожил большую часть своей жизни. Мебели нет совсем, но где-то здесь ты зарыл клад." | ||
описание = "волшебная пещера" | описание = "волшебная пещера" | ||
+ | //... | ||
} | } | ||
− | // | + | |
− | + | ||
+ | для предметов: | ||
+ | *описание | ||
+ | *полное_описание | ||
+ | *предмет_по_месту | ||
+ | *снаружи_персонажа | ||
+ | unique меч | ||
+ | { //... | ||
+ | полное_описание = "это старинный заколдованный тесак, умеющий танцевать джигу. | ||
+ | А кто не хлопает - тому он обрубает уши." | ||
+ | описание = "старинный заколдованный тесак, умеющий танцевать джигу" | ||
+ | предмет_по_месту = "старинный тесак возлежит на своей не менее старинной подставке" | ||
+ | снаружи_персонажа = "ты вооружён заколдованным мечом" | ||
+ | //... | ||
+ | } | ||
+ | |||
+ | |||
+ | для персонажей: | ||
+ | *описание | ||
+ | *полное_описание | ||
+ | *персонаж_по_месту | ||
ГГ.полное_описание = "ты старый зеленый гоблин, морщины времени залегли на твоём лице глубокими складками." | ГГ.полное_описание = "ты старый зеленый гоблин, морщины времени залегли на твоём лице глубокими складками." | ||
ГГ.персонаж_по_месту = "здесь ты думаешь о смысле жизни" | ГГ.персонаж_по_месту = "здесь ты думаешь о смысле жизни" | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
===неиспользуемые глаголы=== | ===неиспользуемые глаголы=== | ||
Строка 216: | Строка 260: | ||
В этой игре ты не можешь уничтожить свой меч! | В этой игре ты не можешь уничтожить свой меч! | ||
+ | ===результаты урока=== | ||
+ | Если Вы все правильно сделали, после запуска игры Вы можете получить нечто подобное: | ||
+ | ТОМ - Текстовая Основа Миростроения v.0.9.2.8 beta. ASBer(C)2008-2009 | ||
+ | Введите '?', 'help' или 'помощь' для справки. | ||
+ | |||
+ | > run | ||
+ | Моя первая игра | ||
+ | В этой игре вы узнаете о истории любви и ненависти, а также постигните смысл | ||
+ | жизни. | ||
+ | Пещера | ||
+ | Это пещера, в которой ты прожил большую часть своей жизни. Мебели нет совсем, но | ||
+ | где-то здесь ты зарыл клад. | ||
+ | |||
+ | > осм | ||
+ | Волшебная пещера. Старинный тесак возлежит на своей не менее старинной | ||
+ | подставке. Здесь ты думаешь о смысле жизни. | ||
+ | |||
+ | > возьми тесак гоблина | ||
+ | Ты взял тесак из пещеры. | ||
+ | |||
+ | > инв | ||
+ | У тебя есть заколдованный тесак. | ||
+ | |||
+ | > осм себя | ||
+ | Ты старый зеленый гоблин, морщины времени залегли на твоём лице глубокими | ||
+ | складками. | ||
+ | |||
+ | > осм себя | ||
+ | Ты выглядишь как обычно, ты вооружён заколдованным мечом. | ||
+ | |||
+ | > убей врагов своим волшебным мечом | ||
+ | В этой игре ты не можешь убить врагов своим волшебным мечом! | ||
+ | |||
+ | > осм меч | ||
+ | Это старинный заколдованный тесак, умеющий танцевать джигу. | ||
+ | А кто не хлопает - тому он обрубает уши. | ||
+ | |||
+ | > брось его | ||
+ | Ты положил заколдованный тесак. | ||
+ | |||
+ | > _ | ||
+ | |||
+ | ==Урок 4: NPC== | ||
+ | [[NPC]] - это объект класса "персонаж". | ||
+ | Грань между персонажами и предметами достаточно размыта. | ||
+ | Главное различие в том, что персонажи понимают речь и могут говорить, а предметы нет. | ||
+ | Так, волшебную говорящую чашку лучше сделать персонажем, а спящую царевну - предметом. | ||
+ | Наш ГГ также наследуется от класса "персонаж". | ||
+ | |||
+ | Итак, поместим в нашу пещеру еще одного персонажа: | ||
+ | unique зеркало | ||
+ | { cls = персонаж | ||
+ | Род = "Ср" | ||
+ | по_имени = "зеркал%; СрЕчНдСи; Ип; Зп=о; Ип=о; Рп=а; Дп=у; Вп=о; Тп=ом; Пп=е;" | ||
+ | описание = "простое волшебное говорящее зеркало" | ||
+ | полное_описание = "Гладкая поверхность отполированного оникса отражает всю пещеру, мягкое свечение камня завораживает. В пещере зеркало появилось так давно, что даже старый гоблин не помнит когда это было. Иногда зеркало разговаривает с гоблином, иногда гоблин с зеркалом^^^" | ||
+ | персонаж_по_месту = "на стене пещеры висит зеркало странной формы" | ||
+ | |||
+ | пещера + this | ||
+ | } | ||
+ | Из нового здесь только свойство Род. | ||
+ | Все персонажи по умолчанию имеют мужской род - Мр, а для зеркала необходимо указать средний род - Ср. | ||
+ | |||
+ | Загрузим игру и попробуем осмотреть пещеру: | ||
+ | > осм | ||
+ | Волшебная пещера. Старинный тесак возлежит на своей не менее старинной | ||
+ | подставке. Здесь ты думаешь о смысле жизни и на стене пещеры висит зеркало | ||
+ | странной формы. | ||
+ | Мы видим, что зеркало отображается не вместе с тесаком (предмет), а после ГГ (персонаж), что не очень хорошо. | ||
+ | Попробуем исправить это: | ||
+ | unique зеркало | ||
+ | { //... | ||
+ | this.предмет_по_месту = "на стене пещеры висит зеркало странной формы" | ||
+ | персонаж_по_месту = нет | ||
+ | //... | ||
+ | } | ||
+ | Мы убрали описание для персонажа и добавили описание предмета. Зеркало - это всё же не полноценный персонаж. | ||
+ | |||
+ | Чтобы в описании пещеры зеркало выводилось перед описанием меча, объект "зеркало" в коде игры необходимо поместить перед объектом "меч". | ||
+ | > осмотри свою пещеру | ||
+ | Волшебная пещера. На стене пещеры висит зеркало странной формы и старинный тесак | ||
+ | возлежит на своей не менее старинной подставке. Здесь ты думаешь о смысле жизни. | ||
+ | |||
+ | |||
+ | NPC, унаследованный от класса "персонаж", имеет теже возможности и может выполнять все команды, что и ГГ, при чём делает это беспрекословно: | ||
+ | > зеркало, возьми меч | ||
+ | Зеркало взяло меч из пещеры. | ||
+ | |||
+ | > зеркало, инв | ||
+ | Зеркало: у меня есть заколдованный тесак. | ||
+ | |||
+ | > зеркало, дай мне мой меч | ||
+ | Зеркало дало тебе меч. | ||
+ | Чтобы сделать поведение зеркала более реалистичным, перегрузим метод '''свобода_воли()''' | ||
+ | unique зеркало | ||
+ | { //... | ||
+ | свобода_воли(Obj) | ||
+ | { switch(act) | ||
+ | //выполняемые зеркалом действия | ||
+ | case(осмотрел) return да | ||
+ | case(осмотрелся) return да | ||
+ | case(сказал) return да | ||
+ | //действия, которые зеркало отказывается делать | ||
+ | case(инвентарь) this > "да у меня даже полочки нет, какой инвентарь?" | ||
+ | case(взял) this > "и чем же я по твоему должно взять {Obj*Вп}?" | ||
+ | case() this > "мы, волшебные зеркала, такого не делаем!" | ||
+ | return нет //отказ | ||
+ | } | ||
+ | //... | ||
+ | } | ||
+ | Чтобы другие персонажи не пытались ничего давать зеркалу, перегрузим метод '''может_не_взять()''' | ||
+ | unique зеркало | ||
+ | { //... | ||
+ | может_не_взять() | ||
+ | { | ||
+ | return "зеркало не может взять это^^^" | ||
+ | } | ||
+ | //... | ||
+ | } | ||
+ | или, чтобы зеркало отказывалось брать передаваемые ему предметы, перегрузим метод '''не_взял()''' | ||
+ | unique зеркало | ||
+ | { //... | ||
+ | не_взял(Obj) | ||
+ | { %Ты протянул {Obj.lex*Вп} зеркалу. | ||
+ | this > "зачем мне {Obj}? мне это не надо." | ||
+ | return нет //отказ | ||
+ | } | ||
+ | //... | ||
+ | } | ||
+ | |||
+ | |||
+ | Теперь зеркало ведёт себя как полагается зеркалам: | ||
+ | > зеркало, возьми тесак | ||
+ | Зеркало: и чем же я по твоему должно взять заколдованный тесак? | ||
+ | |||
+ | > зеркало, инвентарь | ||
+ | Зеркало: да у меня даже полочки нет, какой инвентарь? | ||
+ | |||
+ | > дай тесак зеркалу | ||
+ | Зеркало не может взять это... | ||
+ | |||
+ | > зеркало, осмотри меня | ||
+ | Зеркало: ты старый зеленый гоблин, морщины времени залегли на твоём лице | ||
+ | глубокими складками. | ||
+ | |||
+ | ==Урок 5: Дополнительные локации, карта и стороны света== | ||
+ | Расширим нашу пещеру, еще добавив в неё локации. | ||
+ | Это будут проход на север и зал, к которому он ведет. | ||
+ | |||
+ | Новые локации делаем так-же как во 2м уроке: | ||
+ | location проход | ||
+ | { cls = место | ||
+ | title = "узкий проход" | ||
+ | описание = "Небольшой коридор, ведущий в утробу пещеры." | ||
+ | } | ||
+ | location зал | ||
+ | { cls = место | ||
+ | title = "зал" | ||
+ | описание = "Неровный круглый зал с высоким каменным потолком." | ||
+ | } | ||
+ | |||
+ | Чтобы соеденить локации друг с другом, нам необходимо разместить их на карте. | ||
+ | Для этого необходимо подключить еще один модуль библиотеки - map.tml | ||
+ | //подключим модуль с картой | ||
+ | include "std.lib\map.tml" | ||
+ | Размещаем наши локации на карте: | ||
+ | пещера.отметить_на_карте(1,1,1) | ||
+ | проход.отметить_на_карте(1,2,1) | ||
+ | зал.отметить_на_карте(1,3,1) | ||
+ | Метод '''отметить_на_карте(x,y,z)''' размещает локацию в заданных координатах карты. | ||
+ | Локации, размещенные рядом, автоматически соединяются проходами. | ||
+ | |||
+ | Этот же модуль отвечает за перемещения по компасным направлениям. | ||
+ | |||
+ | Смотрим, что у нас получилось: | ||
+ | Моя первая игра | ||
+ | В этой игре вы узнаете об истории любви и ненависти, а также постигните смысл | ||
+ | жизни. | ||
+ | |||
+ | Пещера | ||
+ | Это пещера, в которой ты прожил большую часть своей жизни. Мебели нет совсем, но | ||
+ | где-то здесь ты зарыл клад. | ||
+ | |||
+ | > иди на север | ||
+ | Ты ушёл на север, в узкий проход. | ||
+ | |||
+ | Узкий проход | ||
+ | Небольшой коридор, ведущий в утробу пещеры. Здесь ты думаешь о смысле жизни. | ||
+ | |||
+ | > иди на север | ||
+ | Ты ушёл на север, в зал. | ||
+ | |||
+ | Зал | ||
+ | Неровный круглый зал с высоким каменным потолком. Здесь ты думаешь о смысле | ||
+ | жизни. | ||
+ | |||
+ | > иди на север | ||
+ | На север не пройти. | ||
+ | |||
+ | > иди на юг | ||
+ | Ты ушёл на юг, в узкий проход. | ||
+ | |||
+ | Узкий проход | ||
+ | Небольшой коридор, ведущий в утробу пещеры. Здесь ты думаешь о смысле жизни. | ||
+ | |||
+ | > иди на юг | ||
+ | Ты ушёл на юг, в пещеру. | ||
+ | |||
+ | Пещера | ||
+ | Волшебная пещера на стене пещеры висит зеркало странной формы и старинный тесак | ||
+ | возлежит на своей не менее старинной подставке. Здесь ты думаешь о смысле жизни. | ||
+ | |||
+ | > иди на юг | ||
+ | На юг не пройти. | ||
+ | |||
+ | ==Урок 6: Менюшные диалоги с NPC== | ||
+ | пишется... | ||
[[Категория:Документация ТОМ]] | [[Категория:Документация ТОМ]] |
Текущая версия на 19:47, 10 февраля 2010
Для выполнения уроков Вам понадобится стандартная библиотека из Пакета библиотек ТОМ.
После распаковки библиотеки свои файлы рекомендуется размещать в каталоге \Libs4TOM , относительно которого в примерах указаны все пути.
Содержание
Урок 1: Комментарии, вывод текста, запуск игры
ТОМ проигрывает обычные планарные текстовые файлы, редактировать которые можно в любом блокноте.
Для удобства запуска расширение файла можно поменять на .tom, но это не обязательно, можно оставить .txt
Итак, у нас есть новый, чистый, только что созданный файл "my_game.tom", открытый в блокноте.
В любой игре обязательно встречаются комментарии, которые никак не влияют на выполнение программы, но при этом очень важны.
В ТОМе комментарии начитаются со знаков "//" и продолжаются до конца строки.
Пример:
//этот текстовый файл - моя первая игра
Для того чтобы вывести на экран любую текстовую строку используется оператор "%". Все символы, следующие после % и до конца строки будут показаны игроку.
Пример:
//выводим название игры и вводную часть %Моя первая игра %В этой игре вы узнаете о истории любви и ненависти, а также постигните смысл жизни.
После сохранения файла его можно открыть в плеере ТОМ.
Сделать это можно несколькими способами:
1. Запустить плеер \Libs4TOM\Bin\constom.exe, в нём набрать команду >run и в открывшемся диалоге выбрать файл my_game.tom
2. Для запуска игры создать .bat - файл с командой из одной строки: Bin\constom.exe my_game.tom
3. Привязать расширение .tom к файлу \Libs4TOM\Bin\constom.exe средствами операционной системы Windows
Если после запуска игры любым способом в окне плеера вы увидите:
Моя первая игра В этой игре вы узнаете о истории любви и ненависти, а также постигните смысл жизни.
первый урок можно считать успешно пройденным.
Урок 2: Первая локация и главный герой с волшебным тесаком
В любой игре обязательно должен быть главный герой - персонаж, управляемый игроком.
Также необходимо описание места в котором действует главный герой.
В текстовых квестах все пространство игры традиционно разбивается на локации. Нам для начала необходима хотя бы одна локация.
Так как ТОМ использует объектно-ориентированной язык программирования, всё что нам необходимо должно быть описано как объекты. Для того чтобы не писать все объекты с нуля, мы воспользуемся модулем стандартной библиотеки main.tml , который содержит необходимые нам классы объектов.
Первое что требуется - это подключить модуль main.tml к нашей игре. Это мы сделаем командой:
//подключим основной модуль стандартной библиотеки include "std.lib\main.tml"
которую вставим в самое начало нашего файла.
Далее создаём первую локацию в нашей игре:
location пещера { cls = место }
В этом тексте:
- location - зарезервированное слово указывающее категорию создаваемого объекта;
- пещера - программное имя нашей локации. Именно так мы будем обращаться к объекту локации из кода игры;
- { } - текст в фигурных скобках служит описанием созданного объекта;
- cls = место - выражение, указывающее класс созданного объекта;
- cls - зарезервированное слово, использующееся для доступа к классу объекта;
- = - оператор присвоения значения;
- место - класс, определенный в модуле main.tml и описывающий самые общие свойства локаций.
Далее разберемся с главным героем.
В модуле main.tml уже создан объект с именем ГГ, подходящий на роль главного героя. Всё что нам требуется - это поместить ГГ в нашу пещеру:
пещера + ГГ
Оператор "+" примененный к двум объектам помещает объект справа в тот объект что слева от оператора.
В данном случае мы добавили ГГ в пещеру
И для полноты картины поместим в локацию наш первый предмет:
unique меч { cls = предмет пещера + this }
В этом примере должно быть всё уже понятно.
Итого, у нас должно получиться:
//подключим основной модуль стандартной библиотеки include "std.lib\main.tml" //выводим название игры и вводную часть %Моя первая игра %В этой игре вы узнаете о истории любви и ненависти, а также постигните смысл жизни. //создаём основную локацию location пещера { cls = место } //помещаем ГГ в пещеру пещера + ГГ //создаем меч и помещаем его в пещеру unique меч { cls = предмет пещера + this }
После запуска этого файла должно получиться что-то подобное:
Моя первая игра В этой игре вы узнаете о истории любви и ненависти, а также постигните смысл жизни. Пещера Это некоторое место - пещера. Здесь есть меч. Ты находишься тут.
Обратите внимание, что "пещера" и "меч" выделяются красным цветом. Это говорит о том, что мы не задали для них наименования и вместо него используется внутреннее имя. Но тем неменее уже сейчас можно опробывать некоторые команды. Максимум что мы можем, это осмотреться, осмотреть себя, заглянуть в свой инвентарь:
> осмотрись Это некоторое место - пещера. Здесь есть меч. Ты находишься тут. > осмотри себя Ты выглядишь как обычно. > инвентарь У тебя ничего нет.
В результате 2го урока мы получили безликую стандартную локацию и такого же безликого героя в ней. Как придать индивидуальность объектам игры читайте далее.
Урок 3: Авторские описания и дополнительные возможности
наименования
Стандартная библиотека требует обязательно указывать наименования предметов, локаций и персонажей.
Наименование обязательно должно содержать все словоформы, т.к. оно участвует в построении автоматически генерируемых сообщении и используется в парсинге команд:
location пещера { //... наименование = "пещер%; ЖрЕчНдСи; Ип; Ип=а; Рп=ы; Дп=е; Вп=у; Тп=ой; Тп=ою; Пп=е;" //... }
Здесь:
- пещер%; - основа лексемы. Для образования словоформ вместо % подставляются различные окончания.
- ЖрЕчНдСи; - свойства лексемы:
- Жр - женский род;
- Еч - единственное число;
- Нд - неодушевлённое;
- Си - Существительное имя;
- Ип; - Форма по умолчанию. Если не указано другого согласования, будет применена форма именительного падежа.
- Ип=а; - окончание словоформы для именительного падежа;
- Рп=ы; - для родительного падежа;
- Дп=е; - для дательного падежа;
- Вп=у; - для винительного падежа;
- Тп=ой; - для творительного падежа;
- Тп=ою; - 2е окончание для творительного падежа;
- Пп=е; - окончание для предложного падежа.
Для меча указываем наименование в виде словосочетания.
Для генерации текстов это вполне подходит, но для парсера надо повторить каждое слово отдельно.
Если предмет можно назвать несколькими словами, все синонимы также необходимо добавить:
unique меч { //... наименование = "заколдованн% тесак%; МрЕчНдСи; Ип; Ип=ый,; Рп=ого,а; Дп=ому,у; Вп=ый,; Тп=ым,ом; Пп=ом;е" this.тесак = "тесак%; МрЕчНдСи; Ип; Ип=; Рп=а; Дп=у; Вп=; Тп=ом; Пп=е" this.заколдованный = "заколдованн%; МрЕчНдПи; Ип; Ип=ый; Рп=ого; Дп=ому; Вп=ый; Тп=ым; Пп=ом" this.меч = "меч%; МрЕчНдСи; Ип; Ип=; Рп=а; Дп=у; Вп=; Тп=ом; Пп=е" //... }
"заколдованн%; МрЕчНдПи; Ип; Ип=ый; Рп=ого; Дп=ому; Вп=ый; Тп=ым; Пп=ом" - здесь в свойствах лексемы
- Мр - мужской род;
- Пи - прилагательное имя.
Для персонажей свойство "наименование" уже определено в классе "персонаж".
Перегружать его нельзя, чтобы не поломать механизм местоимений.
Для указания имен персонажей используется свойство "по_имени".
Также для персонажей необходимо указывать звательный падеж - Зп:
ГГ.по_имени = "гоблин%; МрЕчОдСи; Ип; Зп=; Ип=; Рп=а; Дп=у; Вп=а; Тп=ом; Пп=е"
"гоблин%; МрЕчОдСи; Ип; Зп=; Ип=; Рп=а; Дп=у; Вп=а; Тп=ом; Пп=е" - здесь
- Од - одушевлённое;
- Зп=; - пустое окончание для звательного падежа.
примечания:
- Вместо "наименование" можно писать "title". Оба слова являются зарезервированными ключевыми словами интерпретатора и абсолютно равнозначны.
- Для лучшего понимания лексем, их согласования и словообразования смотрите темы ТОМ: Лексема и ТОМ: Морфологический ключ.
флаги и отношения
Для настройки поведения предметов стандартная библиотека предназначает следующие свойства:
- можно_взять - флаг, по умолчанию "нет"
- чей - отношение собственности
unique меч { //... можно_взять = да чей = ГГ //принадлежит гоблину //... }
описания
Попробуем заменить стандартные скучные описания своими собственными.
Для авторских описаний объектов стандартная библиотека предназначает следующие свойства:
для локаций:
- описание
- полное_описание
location пещера { //... полное_описание = "Это пещера, в которой ты прожил большую часть своей жизни. Мебели нет совсем, но где-то здесь ты зарыл клад." описание = "волшебная пещера" //... }
для предметов:
- описание
- полное_описание
- предмет_по_месту
- снаружи_персонажа
unique меч { //... полное_описание = "это старинный заколдованный тесак, умеющий танцевать джигу. А кто не хлопает - тому он обрубает уши." описание = "старинный заколдованный тесак, умеющий танцевать джигу" предмет_по_месту = "старинный тесак возлежит на своей не менее старинной подставке" снаружи_персонажа = "ты вооружён заколдованным мечом" //... }
для персонажей:
- описание
- полное_описание
- персонаж_по_месту
ГГ.полное_описание = "ты старый зеленый гоблин, морщины времени залегли на твоём лице глубокими складками." ГГ.персонаж_по_месту = "здесь ты думаешь о смысле жизни"
неиспользуемые глаголы
Модуль main.tml содержит в себе шаблоны для очень ограниченного набора команд.
На каждую команду для которой не подошел ни один шаблон из модуля main.tml парсер выдаёт ошибку:
Это мне непонятно...
Чтобы сделать игру более "понятливой" необходимо подключить модуль UnusVerb.tml в котором содержатся описания ошибок для весьма широкого спектра команд. Модуль UnusVerb.tml желательно подключать самым первым до подключения всех остальных модулей. В этом случае реакцию на команду парсер будет искать в UnusVerb.tml в самую последнюю очередь.
//подключим модуль с неиспользуемыми глаголами include "std.lib\UnusVerb.tml" //подключим основной модуль стандартной библиотеки include "std.lib\Main.tml"
Теперь на большинство непредусмотренных в игре команд будут выдаваться индивидуальные сообщения:
> сломай свой меч В этой игре ты не можешь уничтожить свой меч!
результаты урока
Если Вы все правильно сделали, после запуска игры Вы можете получить нечто подобное:
ТОМ - Текстовая Основа Миростроения v.0.9.2.8 beta. ASBer(C)2008-2009 Введите '?', 'help' или 'помощь' для справки. > run Моя первая игра В этой игре вы узнаете о истории любви и ненависти, а также постигните смысл жизни. Пещера Это пещера, в которой ты прожил большую часть своей жизни. Мебели нет совсем, но где-то здесь ты зарыл клад. > осм Волшебная пещера. Старинный тесак возлежит на своей не менее старинной подставке. Здесь ты думаешь о смысле жизни. > возьми тесак гоблина Ты взял тесак из пещеры. > инв У тебя есть заколдованный тесак. > осм себя Ты старый зеленый гоблин, морщины времени залегли на твоём лице глубокими складками. > осм себя Ты выглядишь как обычно, ты вооружён заколдованным мечом. > убей врагов своим волшебным мечом В этой игре ты не можешь убить врагов своим волшебным мечом! > осм меч Это старинный заколдованный тесак, умеющий танцевать джигу. А кто не хлопает - тому он обрубает уши. > брось его Ты положил заколдованный тесак. > _
Урок 4: NPC
NPC - это объект класса "персонаж". Грань между персонажами и предметами достаточно размыта. Главное различие в том, что персонажи понимают речь и могут говорить, а предметы нет. Так, волшебную говорящую чашку лучше сделать персонажем, а спящую царевну - предметом. Наш ГГ также наследуется от класса "персонаж".
Итак, поместим в нашу пещеру еще одного персонажа:
unique зеркало { cls = персонаж Род = "Ср" по_имени = "зеркал%; СрЕчНдСи; Ип; Зп=о; Ип=о; Рп=а; Дп=у; Вп=о; Тп=ом; Пп=е;" описание = "простое волшебное говорящее зеркало" полное_описание = "Гладкая поверхность отполированного оникса отражает всю пещеру, мягкое свечение камня завораживает. В пещере зеркало появилось так давно, что даже старый гоблин не помнит когда это было. Иногда зеркало разговаривает с гоблином, иногда гоблин с зеркалом^^^" персонаж_по_месту = "на стене пещеры висит зеркало странной формы" пещера + this }
Из нового здесь только свойство Род. Все персонажи по умолчанию имеют мужской род - Мр, а для зеркала необходимо указать средний род - Ср.
Загрузим игру и попробуем осмотреть пещеру:
> осм Волшебная пещера. Старинный тесак возлежит на своей не менее старинной подставке. Здесь ты думаешь о смысле жизни и на стене пещеры висит зеркало странной формы.
Мы видим, что зеркало отображается не вместе с тесаком (предмет), а после ГГ (персонаж), что не очень хорошо. Попробуем исправить это:
unique зеркало { //... this.предмет_по_месту = "на стене пещеры висит зеркало странной формы" персонаж_по_месту = нет //... }
Мы убрали описание для персонажа и добавили описание предмета. Зеркало - это всё же не полноценный персонаж.
Чтобы в описании пещеры зеркало выводилось перед описанием меча, объект "зеркало" в коде игры необходимо поместить перед объектом "меч".
> осмотри свою пещеру Волшебная пещера. На стене пещеры висит зеркало странной формы и старинный тесак возлежит на своей не менее старинной подставке. Здесь ты думаешь о смысле жизни.
NPC, унаследованный от класса "персонаж", имеет теже возможности и может выполнять все команды, что и ГГ, при чём делает это беспрекословно:
> зеркало, возьми меч Зеркало взяло меч из пещеры. > зеркало, инв Зеркало: у меня есть заколдованный тесак. > зеркало, дай мне мой меч Зеркало дало тебе меч.
Чтобы сделать поведение зеркала более реалистичным, перегрузим метод свобода_воли()
unique зеркало { //... свобода_воли(Obj) { switch(act) //выполняемые зеркалом действия case(осмотрел) return да case(осмотрелся) return да case(сказал) return да //действия, которые зеркало отказывается делать case(инвентарь) this > "да у меня даже полочки нет, какой инвентарь?" case(взял) this > "и чем же я по твоему должно взять {Obj*Вп}?" case() this > "мы, волшебные зеркала, такого не делаем!" return нет //отказ } //... }
Чтобы другие персонажи не пытались ничего давать зеркалу, перегрузим метод может_не_взять()
unique зеркало { //... может_не_взять() { return "зеркало не может взять это^^^" } //... }
или, чтобы зеркало отказывалось брать передаваемые ему предметы, перегрузим метод не_взял()
unique зеркало { //... не_взял(Obj) { %Ты протянул {Obj.lex*Вп} зеркалу. this > "зачем мне {Obj}? мне это не надо." return нет //отказ } //... }
Теперь зеркало ведёт себя как полагается зеркалам:
> зеркало, возьми тесак Зеркало: и чем же я по твоему должно взять заколдованный тесак? > зеркало, инвентарь Зеркало: да у меня даже полочки нет, какой инвентарь? > дай тесак зеркалу Зеркало не может взять это... > зеркало, осмотри меня Зеркало: ты старый зеленый гоблин, морщины времени залегли на твоём лице глубокими складками.
Урок 5: Дополнительные локации, карта и стороны света
Расширим нашу пещеру, еще добавив в неё локации. Это будут проход на север и зал, к которому он ведет.
Новые локации делаем так-же как во 2м уроке:
location проход { cls = место title = "узкий проход" описание = "Небольшой коридор, ведущий в утробу пещеры." } location зал { cls = место title = "зал" описание = "Неровный круглый зал с высоким каменным потолком." }
Чтобы соеденить локации друг с другом, нам необходимо разместить их на карте. Для этого необходимо подключить еще один модуль библиотеки - map.tml
//подключим модуль с картой include "std.lib\map.tml"
Размещаем наши локации на карте:
пещера.отметить_на_карте(1,1,1) проход.отметить_на_карте(1,2,1) зал.отметить_на_карте(1,3,1)
Метод отметить_на_карте(x,y,z) размещает локацию в заданных координатах карты. Локации, размещенные рядом, автоматически соединяются проходами.
Этот же модуль отвечает за перемещения по компасным направлениям.
Смотрим, что у нас получилось:
Моя первая игра В этой игре вы узнаете об истории любви и ненависти, а также постигните смысл жизни. Пещера Это пещера, в которой ты прожил большую часть своей жизни. Мебели нет совсем, но где-то здесь ты зарыл клад. > иди на север Ты ушёл на север, в узкий проход. Узкий проход Небольшой коридор, ведущий в утробу пещеры. Здесь ты думаешь о смысле жизни. > иди на север Ты ушёл на север, в зал. Зал Неровный круглый зал с высоким каменным потолком. Здесь ты думаешь о смысле жизни. > иди на север На север не пройти. > иди на юг Ты ушёл на юг, в узкий проход. Узкий проход Небольшой коридор, ведущий в утробу пещеры. Здесь ты думаешь о смысле жизни. > иди на юг Ты ушёл на юг, в пещеру. Пещера Волшебная пещера на стене пещеры висит зеркало странной формы и старинный тесак возлежит на своей не менее старинной подставке. Здесь ты думаешь о смысле жизни. > иди на юг На юг не пройти.
Урок 6: Менюшные диалоги с NPC
пишется...