Интерактивные истории, текстовые игры и квесты
Регистрация / Вход
Посетите наш новый сайт AXMAJS.RU
Пишем интерактивную историю вместе. Часть 21-я
Борис Семёнов (Morych), 11.11.13 | Практика ASM
Продолжаем рассматривать пример использования одномерных массивов. Загадку игроку мы загадали, теперь наша задача — предоставить игроку возможность эту загадку решить. Конечно же, герой должен видеть содержимое каждого сундука, а ещё нужно научить героя вытаскивать из сундука верхний предмет и помещать его в любой другой сундук. А чтобы решение загадки не было совсем уж простым, мы ограничим вместимость каждого из сундуков.Рисунок 15 — Решаем загадку.
Полный код нового параграфа «Сундуки» будет выглядеть следующим образом:
Сундуки
<<display 'Новая сцена'>>
<<if $сундук eq -1>>
<<set $сцена = "Новый дом">>
<<set $место = 0>>
<<elseif $сундук eq $сундук_1>>
<<set $сцена = "Первый сундук">>
<<set $место = 11>>
<<elseif $сундук eq $сундук_2>>
<<set $сцена = "Второй сундук">>
<<set $место = 9>>
<<else>>
<<set $сцена = "Третий сундук">>
<<set $место = 7>>
<<endif>>
<<display 'Заголовок'>>
<<if $место gt 0>>
<<set $текст = "">>
<<set $число = $сундук.length + $действие>>
<<loop $число>>
<<set $текст = $текст + "■">>
<<endloop>>
<<set $место = Math.max(0, $место - $число)>>
<<loop $место>>
<<set $текст = $текст + "□">>
<<endloop>>
===<<print $текст>>===
<<endif>>
<<if $действие eq 0>>
<<set $предмет_сундука = "">>
<<if $сундук eq -1>>
Я посмотрел на каждый из трёх сундуков, решая, в который бы из них заглянуть. Первый сундук был самым большим и старым, его доски давно прокоптились и потемнели, но стягивающие их железные полосы делали сундук одновременно и самым крепким. Второй сундук был немного поменьше и гораздо новее, его стенки и крышка светились белизной. А третий сундук был сделан совсем недавно и приятно пахнул свежим деревом, крышку его покрывала искусная и замысловатая резьба.
Мне подумалось, что первый сундук лучше всего подойдёт для добра главы семейства, второй можно использовать для хранения кухонной утвари, а третий сундук -- словно бы нарочно создан для приданного невесты.
<<else>>
<<set $текст = "">>
<<if $сундук.length gt 0>>
<<set $предмет_сундука = $сундук[$сундук.length - 1]>>
<<if $сундук.length gt 1>>
<<set $текст = "увидел там ">>
<<set $номер = 0>>
<<loop $сундук.length - 1>>
<<set $текст = $текст + $сундук[$номер].substr(2)>>
<<if $номер lt $сундук.length - 2>>
<<set $текст = $текст + ", ">>
<<endif>>
<<set $номер++>>
<<endloop>>
<<set $текст = $текст + " и ">>
<<else>>
<<set $текст = "увидел там только ">>
<<endif>>
<<set $текст = $текст + $предмет_сундука.substr(2)>>
<<endif>>
<<if $в_руках.length gt 2>>Держа в руках <<print $в_руках.substr(2)>>, я<<else>>Я<<endif>> заглянул <<if $сундук eq $сундук_1>>в первый<<elseif $сундук eq $сундук_2>>во второй<<else>>в третий<<endif>> сундук <<if $предмет_сундука eq "">> -- там было пусто<<else>> и <<print $текст>><<endif>>.
<<if $место eq 0>>
Похоже, больше ничего в этот сундук и не влезет.
<<endif>>
<<endif>>
<<elseif $действие eq -1>>
Я вытащил <<print $предмет_сундука.substr(2)>> из <<if $сундук eq $сундук_1>>первого<<elseif $сундук eq $сундук_2>>второго<<else>>третьего<<endif>> сундука.
<<set $в_руках = $сундук.pop()>>
<<set $предмет_сундука = "">>
<<set $сундук = -1>>
<<elseif $действие eq 1>>
Я положил <<print $в_руках.substr(2)>> <<if $сундук eq $сундук_1>>в первый<<elseif $сундук eq $сундук_2>>во второй<<else>>в третий<<endif>> сундук.
<<if $показать_подсказки>>
<<if (($сундук eq $сундук_1) and ($в_руках.indexOf("1") gt -1)) or (($сундук eq $сундук_2) and ($в_руках.indexOf("2") gt -1)) or (($сундук eq $сундук_3) and ($в_руках.indexOf("3") gt -1))>>
Ведь именно в этом сундуке и следует хранить <<print $в_руках.substr(2)>>.
<<else>>
Конечно, всякому ясно, что <<print $в_руках.substr(2)>> в этом сундуке хранить нельзя.
<<endif>>
<<endif>>
<<set $сундук.push($в_руках)>>
<<set $в_руках = "">>
<<set $сундук = -1>>
<<endif>>
<<set $действие = 0>>
----
<<if ($предмет_сундука neq "") and ($в_руках eq "") and ($сундук neq -1)>>
[[''Вытащить''|Сундуки {$действие = -1}]] ''<<print $предмет_сундука.substr(2)>>''
<<endif>>
<<if ($в_руках neq "") and ($сундук neq -1) and ($место gt 0)>>
<<if $сундук.length eq 0>>
[[''Положить внутрь''|Сундуки {$действие = 1}]] ''<<print $в_руках.substr(2)>>''
<<else>>
[[''Положить сверху''|Сундуки {$действие = 1}]] ''<<print $в_руках.substr(2)>>''
<<endif>>
<<endif>>
<<if $сундук neq $сундук_1>>
[[''Заглянуть в первый сундук''|Сундуки {$сундук = $сундук_1}]]
<<endif>>
<<if $сундук neq $сундук_2>>
[[''Заглянуть во второй сундук''|Сундуки {$сундук = $сундук_2}]]
<<endif>>
<<if $сундук neq $сундук_3>>
[[''Заглянуть в третий сундук''|Сундуки {$сундук = $сундук_3}]]
<<endif>>
<<if $в_руках eq "">>
[[''Закончить перебирать добро''|Новый дом]]
<<endif>>
Итак, объект «$сундук» изначально равен -1, это означает, что ни один из сундуков не выбран. Если герой выбирает какой-либо сундук, объекту «$сундук» будет присвоена ссылка на соответствующий список. До вызова параграфа «Заголовок» в зависимости от значения объекта «$сундук» зададим название сцены, чтобы игроку было понятнее, с которым сундуком взаимодействует герой. Здесь же установим максимальную вместимость выбранного сундука (объект «$место»). Каждый предмет будет занимать одну условную единицу места.
Под названием сцены показываем уровень заполнения сундука. Для формирования полосы в объект «$текст» используем циклы — макросы «loop» и «endloop». Сначала в строку «$текст» собираем чёрные символы, их количество — это число элементов списка «$сундук» (которое возвращает свойство length) плюс значение объекта «$действие». Объект «$действие» равен -1, если герой достаёт предмет из сундука, и 1, когда герой кладёт предмет в сундук. Если герой просто изучает содержимое сундука, объект «$действие» равен 0. После чёрных добираем в строку «$текст» белые символы, которые показывают свободное место. Обратите внимание, что в объекте «$место» теперь содержится не общая вместимость сундука, а именно оставшееся свободное место.
Для перечисления содержимого выбранного сундука нам снова понадобятся макросы цикла и объект «$текст». При этом, если в сундуке содержится более одного предмета, перед последним предметом мы добавим союз «и». Остальные предметы будем отделять запятыми. Вот почему число повторений цикла равно $сундук.length - 1. В объекте «$номер» содержится индекс очередного предмета, название которого мы добавим к строке «$текст». А перед этим используем метод «substr(2)», чтобы получить только название и не добавлять вместе с названием ещё и номер типа предмета:
<<set $текст = $текст + $сундук[$номер].substr(2)>>
Кроме того, используем «substr(2)» во всех других случаях, когда нужно вывести на экран название предмета. Этот метод вырезает часть строки, начиная с указанного символа. Почему в скобках именно 2? Индексация символов строки начинается с 0. Нулевой символ названия —это номер типа, первый символ — пробел, а собственно название предмета начинается как раз со второго символа.
В объекте «$предмет_сундука» будем хранить тип и название последнего (верхнего) предмета сундука. Именно этот предмет герой и может вытащить. Когда игрок выбирает действие «Вытащить предмет», мы при помощи метода «pop» извлекаем из соответствующего списка последний элемент и помещаем его в объект «$в_руках»:
<<set $в_руках = $сундук.pop()>>
При этом последний элемент исчезает из списка, а длина списка уменьшается на 1. Когда же герой кладёт предмет в сундук, мы используем метод «push», который добавляет указанный объект в конец списка:
<<set $сундук.push($в_руках)>>
Одновременно с этим, если игрок не отключил подсказки, сообщаем, в правильный ли сундук помещён предмет. Так же, как и в параграфе «Новый дом», в условии используем метод строковых объектов «indexOf» для поиска номера типа в названии предмета.
Продолжение следует...Комментарии: 1.
Профиль
Закрыть
Для того, чтобы оставлять комментарии, необходимо зарегистрироваться и подтвердить в профиле указанный
При использовании любых материалов блога обязательно указание ссылки на источник
В комментарии к предыдущей статье я рассказал, как заставить работать параграф "новый дом". А чтобы заработал параграф "сундуки", надо опять же удалить первую строку "<<display 'Новая сцена'>>" и объявить некоторые объекты в параграфе "создание объектов": # Выбранный сундук<<set $сундук = -1>># Верхний предмет в выбранном сундуке<<set $предмет_сундука = "">># Предмет из сундука в руках<<set $в_руках = "">>и все должно заработать :)