ТОМ: Уроки: различия между версиями

Материал из IFВики
Перейти к навигации Перейти к поиску
м (наименования)
м (Урок 5: Дополнительные локации, карта и стороны света)
 
(не показано 40 промежуточных версий этого же участника)
Строка 9: Строка 9:
  
  
И так, у нас есть новый, чистый, только что созданный файл "my_game.tom", открытый в блокноте.
+
Итак, у нас есть новый, чистый, только что созданный файл "my_game.tom", открытый в блокноте.
  
  
Строка 136: Строка 136:
 
Как придать индивидуальность объектам игры читайте далее.
 
Как придать индивидуальность объектам игры читайте далее.
  
==Урок 3: авторские описания и дополнительные возможности==
+
==Урок 3: Авторские описания и дополнительные возможности==
 
===наименования===
 
===наименования===
 
Стандартная библиотека требует обязательно указывать наименования предметов, локаций и персонажей.
 
Стандартная библиотека требует обязательно указывать наименования предметов, локаций и персонажей.
Строка 146: Строка 146:
 
   //...
 
   //...
 
  }
 
  }
 +
Здесь:
 +
*пещер%; - основа лексемы. Для образования словоформ вместо % подставляются различные окончания.
 +
*ЖрЕчНдСи; - свойства лексемы:
 +
**Жр - женский род;
 +
**Еч - единственное число;
 +
**Нд - неодушевлённое;
 +
**Си - Существительное имя;
 +
*Ип; - Форма по умолчанию. Если не указано другого согласования, будет применена форма именительного падежа.
 +
*Ип=а; - окончание словоформы для именительного падежа;
 +
*Рп=ы; - для родительного падежа;
 +
*Дп=е; - для дательного падежа;
 +
*Вп=у; - для винительного падежа;
 +
*Тп=ой; - для творительного падежа;
 +
*Тп=ою; - 2е окончание для творительного падежа;
 +
*Пп=е; - окончание для предложного падежа.
  
  
Строка 151: Строка 166:
 
Для генерации текстов это вполне подходит, но для парсера надо повторить каждое слово отдельно.  
 
Для генерации текстов это вполне подходит, но для парсера надо повторить каждое слово отдельно.  
 
Если предмет можно назвать несколькими словами, все синонимы также необходимо добавить:
 
Если предмет можно назвать несколькими словами, все синонимы также необходимо добавить:
  location меч
+
  unique меч
 
  { //...
 
  { //...
 
   наименование = "заколдованн% тесак%; МрЕчНдСи; Ип; Ип=ый,; Рп=ого,а; Дп=ому,у; Вп=ый,; Тп=ым,ом; Пп=ом;е"
 
   наименование = "заколдованн% тесак%; МрЕчНдСи; Ип; Ип=ый,; Рп=ого,а; Дп=ому,у; Вп=ый,; Тп=ым,ом; Пп=ом;е"
Строка 159: Строка 174:
 
   //...
 
   //...
 
  }
 
  }
 +
"заколдованн%; МрЕчНдПи; Ип; Ип=ый; Рп=ого; Дп=ому; Вп=ый; Тп=ым; Пп=ом" - здесь в свойствах лексемы
 +
*Мр - мужской род;
 +
*Пи - прилагательное имя.
  
  
Строка 166: Строка 184:
 
Также для персонажей необходимо указывать звательный падеж - Зп:
 
Также для персонажей необходимо указывать звательный падеж - Зп:
 
  ГГ.по_имени = "гоблин%; МрЕчОдСи; Ип; Зп=; Ип=; Рп=а; Дп=у; Вп=а; Тп=ом; Пп=е"
 
  ГГ.по_имени = "гоблин%; МрЕчОдСи; Ип; Зп=; Ип=; Рп=а; Дп=у; Вп=а; Тп=ом; Пп=е"
 +
"гоблин%; МрЕчОдСи; Ип; Зп=; Ип=; Рп=а; Дп=у; Вп=а; Тп=ом; Пп=е" - здесь
 +
*Од - одушевлённое;
 +
*Зп=; - пустое окончание для звательного падежа.
  
''Вместо "наименование" можно писать "title".''
+
====примечания:====
''Оба слова являются зарезервированными ключевыми словами интерпретатора и абсолютно равнозначны.''
+
*''Вместо "наименование" можно писать "title". Оба слова являются зарезервированными ключевыми словами интерпретатора и абсолютно равнозначны.''
 +
*''Для лучшего понимания лексем, их согласования и словообразования смотрите темы [[ТОМ: Лексема]] и [[ТОМ: Морфологический ключ]].''
 +
 
 +
===флаги и отношения===
 +
Для настройки поведения предметов стандартная библиотека предназначает следующие свойства:
 +
*'''можно_взять''' - флаг, по умолчанию "нет"
 +
*'''чей''' - отношение собственности
 +
unique меч
 +
{ //...
 +
  можно_взять = да
 +
  чей = ГГ //принадлежит гоблину
 +
  //...
 +
}
  
 
===описания===
 
===описания===
 +
Попробуем заменить стандартные скучные описания своими собственными.
 +
 +
Для авторских описаний объектов стандартная библиотека предназначает следующие свойства:
 +
  
Попробуем заменить стандартные скучные описания своими собственными:  
+
для локаций:
//создаём основную локацию
+
*описание
 +
*полное_описание
 
  location пещера
 
  location пещера
  { cls = место
+
  { //...
  title = "пещер%; ЖрЕчНдСи; Ип; Ип=а; Рп=ы; Дп=е; Вп=у; Тп=ой; Пп=е;"
 
 
   полное_описание = "Это пещера, в которой ты прожил большую часть своей жизни. Мебели нет совсем, но где-то здесь ты зарыл клад."
 
   полное_описание = "Это пещера, в которой ты прожил большую часть своей жизни. Мебели нет совсем, но где-то здесь ты зарыл клад."
 
   описание = "волшебная пещера"
 
   описание = "волшебная пещера"
 +
  //...
 
  }
 
  }
  //помещаем ГГ в комнату
+
 
  пещера + ГГ
+
 
 +
для предметов:
 +
*описание
 +
*полное_описание
 +
*предмет_по_месту
 +
*снаружи_персонажа
 +
unique меч
 +
  { //...
 +
  полное_описание = "это старинный заколдованный тесак, умеющий танцевать джигу.
 +
    А кто не хлопает - тому он обрубает уши."
 +
  описание = "старинный заколдованный тесак, умеющий танцевать джигу"
 +
  предмет_по_месту = "старинный тесак возлежит на своей не менее старинной подставке"
 +
  снаружи_персонажа = "ты вооружён заколдованным мечом"
 +
  //...
 +
  }
 +
 
 +
 
 +
для персонажей:
 +
*описание
 +
*полное_описание
 +
*персонаж_по_месту
 
  ГГ.полное_описание = "ты старый зеленый гоблин, морщины времени залегли на твоём лице глубокими складками."
 
  ГГ.полное_описание = "ты старый зеленый гоблин, морщины времени залегли на твоём лице глубокими складками."
 
  ГГ.персонаж_по_месту = "здесь ты думаешь о смысле жизни"
 
  ГГ.персонаж_по_месту = "здесь ты думаешь о смысле жизни"
Результат:
 
Моя первая игра
 
В этой игре вы узнаете о истории любви и ненависти, а также постигните смысл
 
жизни.
 
Пещера
 
Это пещера, в которой ты прожил большую часть своей жизни. Мебели нет совсем, но
 
где-то здесь ты зарыл клад.
 
 
> осмотри свою пещеру
 
Волшебная пещера. Здесь ты думаешь о смысле жизни.
 
 
> осмотри себя
 
Ты старый зеленый гоблин, морщины времени залегли на твоём лице глубокими складками.
 
 
> осмотри себя
 
Ты выглядишь как обычно.
 
  
 
===неиспользуемые глаголы===
 
===неиспользуемые глаголы===
Строка 218: Строка 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

пишется...