Авторизация
×

Логин (e-mail)

Пароль

Интерактивные истории, текстовые игры, квесты и визуальные новеллы
Гиперкнига

Библиотека    Блог

Пишем интерактивную историю вместе. Часть 5-я

Борис Семёнов (Morych), 19.03.13 | Практика ASM

Первый диалог

Что ж, приступим к реализации диалога с второстепенным персонажем. Как видно из текста параграфа «Дом старейшины», при первом посещении сцены диалог начинает сам дед Закром. При желании герой может продолжить диалог в параграфе «Разговор с дедом». Собственно, поговорить с дедом герою рано или поздно всё же придётся, иначе он просто не продвинется по сюжету.

Оформить диалог можно разными способами. Самый простой — сплошным текстом, как в книгах. Конечно, в интерактивных историях такого способа лучше избегать, потому что читатель перестаёт быть непосредственным участником событий и становится сторонним наблюдателем. Применение этого способа подачи диалога может быть оправдано лишь в самом начале и в конце истории. Либо когда главный герой действительно не участвует в диалоге (разговаривают только второстепенные персонажи). И даже в этом случае лучше предоставить герою возможность вставить словечко-другое.

Будем оформлять диалог в следующем виде: реплика героя, реакция персонажа, варианты реакции героя. В некоторых случаях вариант этот может быть всего один, но пусть читатель его выберет сам, чтобы его взаимодействие с историей не прекращалось. Оптимальное же количество вариантов, как мне кажется, около четырёх. Каждый вариант реакции будет обычной ссылкой на соответствующее продолжение беседы. Таким образом, после выбора одного из вариантов экран очистится, и читатель увидит следующий фрагмент диалога.

Все фрагменты диалога будут содержаться в одном параграфе. Конечно, можно для каждого фрагмента диалога заводить свой параграф. Особенно, если диалогов в истории немного, и все они небольшие. В противном случае мы рискуем рано или поздно в этих параграфах-фрагментах запутаться. Поэтому пусть лучше каждый диалог будет локализован в одном параграфе. Нам потребуется ещё один объект, назовём его «$диалог_дед», который будет отвечать за отображаемый номер фрагмента беседы с дедом Закромом. Не забудем установить начальное значение этого объекта в параграфе «Создание объектов» в 1.

Параграф «Разговор с дедом» будет довольно-таки объёмным, но пугаться не стоит, потому что на самом деле он очень простой. Логика здесь почти такая же, как и при выводе разных описаний сцены.

Разговор с дедом

<<display 'Заголовок'>>
<<if $диалог_дед eq 1>>
    -- Тут такое дело, -- робко начал я, потупив глаза, -- до сих пор в толк не возьму, как приключилось...
    -- А ну цыц! -- сурово прикрикнул дед Закром и пуще прежнего нахмурил брови. -- И как не совестно тебе землицу топтать, под солнцем красным гулять?
    [[Виновато притихнуть|Разговор с дедом {$диалог_дед = 2}]]
    [[Оправдываться|Разговор с дедом {$диалог_дед = 3}]]
<<elseif $диалог_дед eq 2>>
    Под строгим взором деда Закрома я виновато притих, не смея вымолвить ни слова. А старик между тем продолжал бушевать:
    -- Сколько уж я в старейшинах хожу, а допрежь не было такого, чтобы в моём селе!.. И чтобы такое!.. Да ты!.. Да это что же!..
    Пока дед Закром подыскивал годные слова для сообразного описания моей вины, я поспешил сменить тему.
    [[Пожаловаться про сгинувшее добро|Разговор с дедом {$диалог_дед = 4}]]
    [[Просить совета|Разговор с дедом {$диалог_дед = 5}]]
<<elseif $диалог_дед eq 3>>
    -- Да что я, нарочно что ли? Ввечеру ещё всё хорошо было, а на утро глядь -- лишь головёшки дымятся.
    -- Это ты что, почивать изволил? -- не поверил своим ушам дед Закром. -- Ночью? Когда самое лихо по земле и бродит!
Что мне было ответить? Да, бывало, так умаешься за день, что на закате в сон клонит, но спал-то я всегда до полуночи, не более.
    [[Виновато притихнуть|Разговор с дедом {$диалог_дед = 2}]]
    [[Пожаловаться про сгинувшее добро|Разговор с дедом {$диалог_дед = 4}]]
<<elseif $диалог_дед eq 4>>
    -- А добра-то у меня столько сгинуло! -- тяжко вздохнул я. -- И лавки, и посуда...
    -- Лавки? -- вскричал дед Закром. -- Посуда?
    Тот час добыв из-за пазухи клочок бересты, он принялся зачитывать, загибая пальцы:
    -- Один стол дубовый струганный, два сундука кованых резных, лавка яблоневая широкая. Три. Лавки. Одно корыто треснувшее конопаченное, пять кадушек дубовых непротекаемых...
    Называемое добро пролетало перед моим мысленным взором и, плавно растворяясь, исчезало навеки. В какой-то момент я даже перестал слышать скрипучий дедов голос и очнулся лишь в самом конце списка.
    -- А ты молвишь посуда! -- закончил дед Закром и спрятал бересту за пазуху.
    [[Просить совета|Разговор с дедом {$диалог_дед = 5}]]
<<elseif $диалог_дед eq 5>>
    -- Что же мне теперь делать, дедушка Закром? Окажи милость, присоветуй!
    -- Что делать, что делать, -- пробурчал старый домовой. -- Может и присоветую, коли верно ты на мои вопросы ответишь.
    [[Слушать вопросы|Разговор с дедом {$диалог_дед = 6}]]
<<elseif $диалог_дед eq 6>>
    -- Вопросы, так вопросы, -- сказал я и подумал: -- Чай, не полный дурень, уж как-нибудь отвечу.
    Дед Закром тем временем огладил бороду, немного пожевал губами и заговорил:
    -- Первый мой вопрос такой. Даже не вопрос, а загадка. Не лает, не кусает, а лихо в дом не пускает -- о ком сии слова сказаны?
    «А загадка-то как бы и не сложная, -- обрадовался я. -- Такими загадками токмо детей стращать!»
    [[Ответить, что это засов|Разговор с дедом {$диалог_дед = 7} {$ответ = '-- Так ведь это засов! -- воскликнул я. -- Которым дверь на ночь запирают.<<br>><<br>>-- А коли не через дверь лихо полезет? -- возразил мне дед. -- Как тут засов твой подсобит? Неверно ты ответил!<<br>><<br>>-- Стало быть, это кот, -- назвал я свой второй вариант.'}]]
    [[Ответить, что это кот|Разговор с дедом {$диалог_дед = 7} {$ответ = '-- Да что тут думать! -- воскликнул я. -- Это же кот!<<br>><<br>>-- Положим, кот и видит нечисть лихую, да только и умеет, что шипеть да спину гнуть дугой, а толку с того чуть! -- возразил мне дед и приговорил: -- Неверно ты ответил!<<br>><<br>>-- Стало быть, это засов, которым дверь на ночь запирают, -- назвал я свой второй вариант.'}]]
<<elseif $диалог_дед eq 7>>
    <<print $ответ>>
    -- Нет! -- рявкнул дед Закром. -- Это ты! Хозяин то есть, хотя какой к лешему из тебя хозяин.
    [[Просить задать другой вопрос|Разговор с дедом {$диалог_дед = 8}]]
<<elseif $диалог_дед eq 8>>
    -- Не серчай, деда Закром! -- взмолился я. -- Спроси меня ещё, уж на этот раз я не оплошаю!
    Старик немного посопел, покряхтел, но спустя какое-то время всё же согласился:
    -- Так и быть... Отвечай, в чём состоит наиглавнейшая забота хозяина: добру учёт вести, коням косицы плести, людские сны блюсти али избу пасти?
    <<set $диалог_дед = 9>>
<<elseif $диалог_дед eq 10>>
    # Фрагмент диалога для неправильных ответов на второй вопрос
    -- Наиглавнейшая забота хозяина, -- молвил я, -- это, знамо дело, <<print $ответ>>
    -- Эх, не выйдет из тебя толкового хозяина, -- покачал головой старик. -- Ступай себе, да не смей показываться, покуда ума-разума не наберёшься.
    [[Уйти|Старое селение {$диалог_дед = 11}]]
<<elseif $диалог_дед eq 11>>
    -- Дедушка Закром, дозволь слово молвить! -- попросил я.
    -- Ну чего тебе? -- недовольно буркнул дед Закром.
    -- Поднабрался я маленько ума-разума, ведаю теперь ответ верный.
    -- Неужто? И в чём же, по-твоему, наиглавнейшая забота хозяина?
    <<set $диалог_дед = 9>>
<<elseif $диалог_дед eq 12>>
    -- Так ведь эти заботы, кои ты назвал, дедушка Закром, все наиглавнейшие! Добрый хозяин всё поспевать обязан. Хоть что одно не доглядишь -- всё хозяйство и развалится.
    -- Хм, -- ухмыльнулся старый домовой. -- Вот теперь ты по уму говоришь, может и будет с тебя толк. Хотя верный ответ дать немудрено, то ли дело справу хозяйскую сладить... А совет мой такой. Надобно тебе новый дом отыскать, который срублен недавно, и где хозяина пока нету. Ежели люди тамошние признают в тебе хозяина, да угощеньице поднесут, стало быть сможешь ты там остаться. Уразумел? Ну, добро. Только вот незадача, нету в нашем селе такого бесхозяйного дома. Придётся тебе в соседнем селе поспрошать. Ежели немедля отправишься, глядишь засветло и доберёшься.
    [[Поблагодарить деда|Разговор с дедом {$диалог_дед = 14}]]
    [[Уйти|Старое селение {$диалог_дед = 13}]]
<<elseif $диалог_дед eq 13>>
    -- Снова ты, -- проворчал старый домовой. -- Зачем на этот раз пожаловал?
    -- Не серчай, дедушка Закром, я ненадолго.
    -- Неужто не уразумел? Отправляйся в соседнее село, да ищи там дом бесхозяйный. Дворов там поболе нашего будет. Глядишь, и отыщется такая изба. Ежели её кто другой не займёт, покуда ты медлишь.
    [[Поблагодарить деда за науку|Разговор с дедом {$диалог_дед = 14}]]
    [[Уйти|Старое селение]]    
<<elseif $диалог_дед eq 14>>
    -- Благодарствую тебе, дедушка Закром, за науку, -- поклонился я старику в пояс.
    -- Выйдешь за околицу, по тропе ступай прямёхонько через лес, -- подсказал напоследок дед Закром. -- Да смотри, никуда с тропы не сворачивай! Всё, ступай, и Сварог тебе в допомогу!
    [[Уйти|Старое селение {$диалог_дед = 15}]]
<<elseif $диалог_дед eq 15>>
    -- Ты ещё здесь? -- удивился дед Закром. -- Поспешать тебе надобно, итак времени сгубил немерено. Чует моё сердце, не к добру промедление.
    Тревога старика передалась и мне. Поблагодарив его ещё раз и распрощавшись, я поспешил отправиться в путь.
    [[Уйти|Старое селение]]    
<<endif>>
# Фрагмент для вывода вариантов ответа на второй вопрос
<<if $диалог_дед eq 9>>
    [[Сказать про добро|Разговор с дедом {$диалог_дед = 10} {$ответ = 'добро хранить да пересчитывать! Без добра и хозяина нету!'}]]
    [[Сказать про коней|Разговор с дедом {$диалог_дед = 10} {$ответ = 'за скотиной глядеть, особливо же за конём! Справный конь -- он всего хозяйства опора!'}]]
    [[Сказать про людей|Разговор с дедом {$диалог_дед = 10} {$ответ = 'людей в избе живущих оберегать! Не красна изба углами, а красна людями!'}]]
    [[Сказать про избу|Разговор с дедом {$диалог_дед = 10} {$ответ = 'избу беречь от лиха всякого! Была бы изба, остальное приложится!'}]]
    [[Сказать, что все те заботы важны|Разговор с дедом {$диалог_дед = 12}]]
<<endif>>

Весь диалог с дедом Закромом состоит из 15 фрагментов. Беседа начинается с фрагмента №1. После заголовка сцены из всего нашего объёмного параграфа будет выведено только 4 строчки: реплика героя, ответ второстепенного персонажа и две ссылки-варианта реакции героя. Вы, должно быть, заметили, что оформление ссылок дополнилось фигурными скобками. В фигурных скобках мы можем устанавливать значения объектов, совсем как в макросе «set». Только присваивание сработает лишь в случае нажатия ссылки. Именно благодаря такой возможности нам и удалось все фрагменты диалога собрать в одном параграфе.

Итак, допустим, читатель выбрал вариант «Оправдываться». Значение объекта «$диалог_дед» установится в 3, и будет осуществлён переход на этот же параграф. Текст на экране обновится, отображая соответствующий фрагмент диалога. И так далее, пока читатель не доберётся до конца диалога. Окончаниями диалога считаются фрагменты, в которых есть ссылки на другой параграф. В нашем случае это будут все фрагменты с вариантом «Уйти», который отправляет читателя на параграф «Старое селение» (фрагменты №10 и с 12 по 15).

Теперь давайте разберёмся с фрагментом №6. Оба варианта в этом фрагменте отправляют читателя на один и тот же фрагмент №7, но с разным значением объекта «$ответ». Этот объект мы будем использовать, как понятно из названия, для хранения ответа героя. Значение объекта «$ответ» также задаётся при помощи фигурных скобок в ссылках. Вообще в ссылках мы можем задавать значения любого числа объектов. Главное, не забывать заключать каждый объект в свою пару фигурных скобок.

В значениях объекта «$ответ» используются макросы «br» (от англ. «break» — «разрыв») которые разрывают строку. Два таких макроса подряд сформируют вертикальный отступ с одной пустой строкой. Таким образом, каждая реплика будет начинаться с нового абзаца. Кстати вместо двойных макросов «br» можно просто нажать клавишу «Enter»:

[[Ответить, что это засов|Разговор с дедом {$диалог_дед = 7} {$ответ = '-- Так ведь это засов! -- воскликнул я. -- Которым дверь на ночь запирают.
-- А коли не через дверь лихо полезет? -- возразил мне дед. -- Как тут засов твой подсобит? Неверно ты ответил!
-- Стало быть, это кот, -- назвал я свой второй вариант.'}]]

Установка значения объекта таким способом в ASM допускается.

Фрагмент №7 начинается с вывода на экран значения объекта «$ответ» при помощи макроса «print». Итоговая реакция второстепенного персонажа на любой из ответов, доступных в 6-м фрагменте, одинакова. Поэтому мы и использовали один фрагмент. Этот же приём с использованием дополнительного объекта применяется и во фрагменте №9.

Но что же сам фрагмент №9 стоит не по порядку? Я специально выделил его из основного блока условных макросов и поместил в самом конце параграфа. Всё дело в том, что во фрагментах №8 и 11 нам нужно вывести один и тот же список вариантов ответа. Можно было бы использовать для этих целей отдельный параграф, который выводить в нужном месте макросом «display». Но мы условились, что поместим весь диалог в один параграф. В каждом из этих фрагментов при помощи макроса «set» мы устанавливаем значение объекта «$диалог_дед» в 9. Таким образом, в этих двух случаях на экране отображаются сразу два фрагмента диалога (8+9 и 11+9).

И про окончания диалога. Хотя переход по ссылкам «Уйти» осуществляется на другой параграф, значение объекта «$диалог_дед» в некоторых случаях всё равно меняется. Это потому что оно устанавливается соответственно номеру фрагмента, с которого начнётся диалог при следующей беседе героя с персонажем.

В качестве самостоятельного упражнения попробуйте написать диалог с другим второстепенным персонажем. Заготовка простейшего диалога:

Параграф-диалог

<<display 'Заголовок'>>

<<if $диалог_персонаж eq 1>>
    Реплика главного героя.
    Реплика второстепенного персонажа.
    [[Реплика героя, вариант 1|Параграф-диалог {$диалог_персонаж = 2}]]
    [[Реплика героя, вариант 2|Параграф-диалог {$диалог_персонаж = 3}]]

<<elseif $диалог_персонаж eq 2>>
    Реплика героя, вариант 1.
    Реакция второстепенного персонажа.
    [[Закончить разговор|Параграф-сцена {$диалог_персонаж = 4}]]

<<elseif $диалог_персонаж eq 3>>
    Реплика героя, вариант 2.
    Реакция второстепенного персонажа.
    [[Закончить разговор|Параграф-сцена {$диалог_персонаж = 4}]]

<<elseif $диалог_персонаж eq 4>>
    Реплика героя.
    Второстепенный персонаж напоминает, что уже разговаривали.
    [[Закончить разговор|Параграф-сцена]]

<<endif>>

Конечно же, можно оформлять диалог и другими способами, позволяя, например, разговаривать на разные темы. Это, правда, потребует более серьёзного программирования, поэтому вернёмся к диалогам позже, когда наш герой встретит кого-нибудь ещё. Пока же перейдём к не менее интересной теме.

Продолжение следует...

Комментарии: 11.

Профиль


Закрыть

Показать все комментарии

uno
28.10.14 00:00

Очень все хорошо расписано! Очень подробно! Мне вот интересно, есть кто освоил программу, не имея навыков программирования? У меня более-менее понятно прошли 1 и 2я статья. Над 3й я сидела-мучалась неделю. А на 4й вообще застряла. Что же будет дальше!! В любом, случае, информация подана очень хорошо, вдохновляет не забрасывать все это дело :)))
Morych
01.11.14 09:39

Большое спасибо за отзыв! Мне очень важно знать мнение читателей. Когда дойдут руки до переиздания учебника после релиза АСМ 3.0, буду стараться подавать материал ещё более доступно :)
Mo555
29.12.16 18:20

Отлично придумано!!! Такой не простой диалог и весь в одном параграфе! Класс!! :) Пошёл оптимизировать свой квест :)

Вообще, выражаю своё восхищение тем, как Вы обстоятельно и подробно с примерами всё объясняете! Очень хорошее пособие по АСМ и вообще по созданию квестов и историй! Спасибо!

Для того, чтобы оставлять комментарии, необходимо зарегистрироваться и подтвердить в профиле указанный e-mail адрес.

При использовании любых материалов блога обязательно указание ссылки на источник