Если вы не знаете Javascript или что это такое, не волнуйтесь! Вы сможете учиться по ходу дела или вообще обойтись без него. То, что мы собираемся изучить, — это инструмент с открытым исходным кодом для создания интерактивных историй — Twine (или см. его веб-сайт).
Это позволяет нам создавать нелинейные истории. Это могут быть презентации, художественная литература или текстовые приключенческие игры. Короче говоря, Twine создает файл HTML со всем содержимым. Итак, это обычная веб-страница, а инструмент — конструктор. Вы можете загрузить такой «веб-сайт» в Интернете или на мобильных платформах, то есть в любом месте, которое может анализировать HTML.
Если вас особенно интересуют игры/интерактивная фантастика, посмотрите обширную их коллекцию. Итак, какие игры возможны? Все они, поскольку мы можем добавить Javascript. Однако проще всего делать текстовые приключенческие игры. Почему? Вам не нужно ничего или много программировать. Вы добавляете истории и связываете их осмысленным образом, используя ссылки. То есть, если вы выберете A, будет показана история AA, если вы выберете B, будет показана история BB.
См. также что вы можете создать с помощью этого инструмента в их документации.
Создание такой страницы занимает несколько минут на сайте Twine (это можно сделать онлайн). Вы можете добавлять Javascript, видео, музыку, изображения, настраивать стили с помощью CSS, связывать и экспериментировать. Это отличный способ начать. Далее я покажу вам другой подход, если вы привыкли программировать в любом редакторе разработчика и хотите контролировать версии.
Сначала попробуйте онлайн, особенно если ваша история/игра невелика и требует лишь небольшой пользовательской функциональности.
Зачем вам может понадобиться Javascript
Вы можете обходиться без него и чувствовать себя прекрасно. Но если у вас есть нестандартные вещи, вы будете использовать некоторые макросы и скрипты. Кто они такие? Представьте себе Twine как ядро, но у него есть разные движки, которые делают разные вещи. Он поддерживает четыре таких движка (форматы историй), чтобы сделать процесс создания более доступным. Каждая из них различается по сложности. В этой статье я буду использовать SugarCube.
Этот формат истории имеет много встроенных вещей, которые могут вам понадобиться. Например:
- Сохранение игры, возобновление ее с сохранения.
- Различные события, на которые нужно реагировать. Например, когда история рендерится, начинается рендеринг и т. д.
- Макросы, т.е. полезные встроенные блоки/функции. Например, кнопки, настраиваемые ссылки, условный рендеринг, установка переменных, манипуляции с DOM и т. д.
- Обработка звука.
- И много других ценных вещей.
Проект Twine в стиле разработчика
Давайте создадим простой проект, в котором мы хотим использовать пользовательские стили Javascript и CSS, но что более важно — мы хотим иметь контроль версий! Я не использую онлайн-версию или настольную версию инструмента, потому что могу управлять историями только как файлами и получать их версии путем фиксации.
Вам нужно будет установить Tweego, инструмент, который может анализировать истории как файлы в любом предпочитаемом текстовом редакторе. Однако помните о его ограничениях:
- На момент написания этой статьи последнее обновление Tweego было два года назад.
- Таким образом, у вас могут не быть всех функций из поддерживаемых форматов историй (например, Sugarcube).
Теперь вам нужно создать папку проекта:
$ mkdir twine-project
$ cd twine-project
$ git init
Вы также можете переместить исполняемый файл Tweego в эту папку и добавить его в .gitignore
Теперь вам решать, как организовать файлы! Примерная структура может выглядеть следующим образом:
.gitignore
README.md
bin/
src/
├─ config.tw
├─ styles/
│ ├─ menu.css
│ ├─ main.css
├─ modules/
│ ├─ menu/
│ │ ├─ menu.tw
│ │ ├─ menu.js
В папке bin
у вас есть исполняемый файл Tweego для создания вывода в формате HTML (мы доберемся до этого). Весь код, связанный с историей (игрой), находится в папке src
. Tweego поместит все файлы Twine(`.tw`), стили CSS, скрипты Javascript в один HTML. Поэтому не имеет значения, какая у вас структура проекта.
Формат шпагата
Теперь ближе к кодировке: что такое config.tw
? Здесь ваш код будет в формате Twine. Загляните в спецификацию. Вы можете назвать этот файл как хотите. Он назван config
для удобочитаемости. Там указываем настройки для нашей игры:
:: StoryTitle My first game
:: StoryData { "ifid": <a serial number of your game>, "format": "SugarCube", "format-version": "2.30.0", "start": <a name of the story that will be shown first> }
:: StoryAuthor <your name if you want>
<<script>> // in case you'll need to have 3rd-party scripts // remove this <<script>> section at all for now importScripts( 'https://cdn.jsdelivr.net/npm/chance' ) <</script>>
Вам нужно сгенерировать серийный номер для вашей игры, т. е. IFID. Подробнее о том, как это сделать, читайте здесь. Но пока вы можете использовать 0000A000-A0E0-00C0-00B0-CF000E000D0E
, чтобы пропустить этот скучный шаг.
format
указывает Tweego, какой формат истории использовать. Мы будем использовать SugarCube
. format-version
— это версия для этого формата истории, в настоящее время поддерживается только 2.30.0
. Однако есть более новые версии (ограничение Tweego).
start
— это история, которая будет показана первой. Создадим файл start.tw
с таким содержимым:
:: StartOfMyGame
This is the first screen of my game, yay!
[[Start playing]] [[Read about the author]]
Здесь ::
указывает идентификатор вашего отрывка (т. е. страницы). Это может быть что угодно, например, :: start-of-my-game
или :: something like this
. Теперь, когда у вас есть идентификатор, измените config.tw
на:
"start": "StartOfMyGame"
После ID прохода(страницы) делайте что хотите. В нашем случае мы написали: "Это первый экран моей игры, ура!", и он будет отображаться как обычный текст, вот и все! [[Start playing]]
— это ссылка на другой отрывок (страницу).
Чтобы преобразовать это в HTML, запустите Tweego (он будет следить за изменениями файлов):
$ ./bin/tweego -w src -o ./output/index.html
Здесь мы говорим ему следить за папкой src
и создавать выходной HTML-код в папке output
как index.html
. Запустите эту команду, и вы увидите вывод HTML в этой папке. Не забудьте добавить output
к .gitignore
. Откройте output/index.html
в браузере, и вы увидите что-то вроде этого (с более темным цветом фона):
Мы создаем ссылки, но нам также необходимо создать такие страницы. Итак, нам нужно изменить start.tw
:
:: StartOfMyGame
This is the first screen of my game, yay!
[[Start playing]] [[Read about the author]]
:: Start playing <<back>> It's another page called "Start playing".
:: Read about the author <<back>> I'm the author. This is my page.
Мы добавили еще две страницы, поэтому всякий раз, когда вы нажимаете, например, «Начать воспроизведение», вы будете перенаправлены на отрывок «Начать воспроизведение»:
Здесь мы видим новую ссылку — Назад! <<back>>
— это макрос SugarCube, который перенаправляет пользователя к предыдущему прохождению (`StartOfMyGame`). Это более удобный способ сделать это, чем каждый раз сохранять историю навигации.
Мы можем создать эти два новых прохода в других файлах или создать все игровые проходы в одном файле. Это не имеет значения, потому что Tweego объединяет все файлы в один HTML-файл. Вам не нужно заботиться об импорте чего-либо!
Добавление Javascript в истории Twine
Давайте представим, что мы хотим хранить некоторую информацию о выборе игрока. Есть два подхода:
- Мы можем использовать макрос
<<set>>
. - Мы можем использовать Javascript.
При использовании <<set>>
:
:: StartOfMyGame
This is the first screen of my game, yay!
<<link "Start playing" "StartPlaying">> <<set $choice to "StartPlaying">> <</link>> <<link "Read about the author" "AboutTheAuthor">> <<set $choice to "AboutTheAuthor">> <</link>>
:: StartPlaying <<back>> It's another page called "Start playing". The choice is <<= $choice>>
:: AboutTheAuthor <<back>> I'm the author. This is my page. The choice is <<= $choice>>
Несколько новых вещей здесь:
<<link>>
macro делает то же самое, что и[[ ]]
, но добавляет больше возможностей для настройки. В нашем случае мы сохранили текст ссылки, но указали другой идентификатор перехода (например, `StartPlaying`). Также мы можем что-то сделать при нажатии на ссылку, например, инструкцию<<set>>
ниже.- Макрос
<<set>>
хранит переменную. <<= $choice>>
— это макрос для оценки выражений. В нашем случае отображается переменная$choice
, которую мы установили ранее.
Мы можем добиться того же, используя Javascript (однако в этом примере это кажется излишне сложным):
:: StartOfMyGame
This is the first screen of my game, yay!
<<link "Start playing" "StartPlaying">> <<script>> State.setVar('$choice', 'StartPlaying (Javascript)') <</script>> <</link>>
:: StartPlaying <<back>> It's another page called "Start playing". The choice is <<= $choice>>
Я удалил второй абзац, чтобы не дублировать код. Вот несколько новых вещей:
- Мы по-прежнему делаем сценарии внутри макроса
<<link>>
. Но сейчас мы используем макрос<<script>>
. Внутри него мы используем методsetVar
глобального объектаState
, который делает то же самое, что и<<set>>
в предыдущем примере. - Мы по-прежнему отображаем переменную
$choice
без использования Javascript, но мы могли бы найти этот HTML-блок с помощью jQuery (который встроен в скрипты SugarCube), а затем установить для него значение$choice
, но в этом нет необходимости.
Когда вы используете Javascript, у вас есть доступ к API формата истории, так что это больше возможностей для настройки. Однако вы можете не столкнуться с такой сложностью в своей игре.
Это все на данный момент! Конечно, в игре есть чем заняться. Но у вас есть документация и инструменты, чтобы открывать и изучать больше самостоятельно.