В этой статье я расскажу, как участвовал в джеме Trust No One и сделал текстовую адвенчуру "ITERVIEW" с помощью движка Phaser и скриптового языка Ink.
Поделюсь опытом подключения inkjs
, подготовки истории, импорта JSON-файла и рендеринга выбора. Если вы хотите создавать игры с нелинейным сюжетом — будет полезно.
Участие в джеме Trust No One от Плейгамы
Совсем недавно закончился джем от Плейгамы под названием "Trust No One". Я люблю "неторопливые" джемы на пару недель, а тут еще и был шанс заработать денежный приз, хоть сильно я на это не рассчитывал. У джема было два обязательных важных требования: игра должна иметь билд для веба, игра должна иметь встроенный SDK от плэйгамы.
Еще до объявления темы я знал в каком жанре буду делать игру. Мне уже давно очень хотелось сделать текстовую адвенчуру. Прежде я видел на итче и Яндексе пару игр которые мне понравились в реализации, это "The Secret Laboratory" и "Среди зомби". По моему обе игры были сделаны на дефолде с использованием скриптового языка ink, ну и я давно задумывал реализовать похожую по стилю игру но на Phaser.
Игру я в итоге сделал, называется она "ITERVIEW" можно в неё при желании поиграть. А здесь я поделюсь опытом и особенностями подключения ink.js в билд игры на Phaser.
Подготовка истории в редакторе ink
Перед тем Как лезть в Phaser нужно подготовить саму историю с помощью редактора ink. Редактор использует специфический синтаксис, который нужно соблюдать что бы история экспортировалась корректно. Этот синтаксис можно обозначить на простом примере.
Вы заходите в тёмную комнату.
+ [Робко, переступить через порог] -> Начало
= Начало
Поздравляю, вы сделали первый шаг!
+ [Осмотреться] -> Осмотреться
+ [Идти вперёд] -> ИдтиВперёд
= Осмотреться
Вы видите стол и маленькую лампу.
+ [Включить лампу] -> Лампа
+ [Вернуться назад] -> ДвигатьсяДальше
= Лампа
Лампа загорелась. Стало чуть светлее!
-> ДвигатьсяДальше
= ИдтиВперёд
Вы прошли чуть дальше по коридору.
-> ДвигатьсяДальше
= ДвигатьсяДальше
Куда двигаться дальше?
+ [Вперёд] -> ИдтиВперёд
+ [Оглянуться по сторонам] -> Осмотреться
В целом все работает на текстовых блоках которые маркируются заголовком со знаком =
. Заголовок не должен содержать пробелов и быть уникальным. В конце блока содержаться варианты ответов, текст внутри скобок показывается игроку, а после идет заголовок блока к которому мы перейдем при клике.
После того как работа над рассказом будет закончена, можно экспортировать json с рассказом для использования в игре.
Подключение inkjs и базовое API
Подключается inkjs очень просто через npm
npm install inkjs
а после импортируем модуль в сцену
import { Story } from 'inkjs';
конечно нужно не забыть импортировать json в preload
this.load.json('inkStory', 'assets/story.json');
после читаем его и используем класс Story из inkjs
const data = this.cache.json.get('inkStory');
this.story = new Story(data);
А дальше все просто, проверяя есть ли еще текст для вывода с помощью canContinue
и выводя следующий блок текста с помощью Continue()
можно выводить блоки текста на экране.
while (this.story.canContinue) {
textBuffer = this.story.Continue();
}
Варианты ответов можно получить через this.story.currentChoices
this.currentChoices = this.story.currentChoices;
this.currentChoices.forEach((choice, index) => {
let choiceText = this.add.text(50, 50, choice.text);
});
Добавление картинок на отдельные реплики
В ink есть очень удобная ситема тегов. Вы просто пишете тег после реплики, например так
= Заголовокблока
Текст блока # тег
Тегов может быть несколько и вы можете получить весь массив с ними используя функцию currentTags
. и удобно привязать любые дейсвия или стиль оформления реплики к тегу.
Заключение
Я надеюсь что вам понравился этот урок и вы нашли в нем полезную информацию.
Если у вас есть вопросы ко мне лично, вы можете написать мне в твиттер или телеграм. Так же приглашаю вас в русскоязычное сообщество разработчиков на Phaser.
Если вы решите поддержать меня материально - ссылка на донат.