Post image

Bubbly Tap: Связанные пузыри

Прошло более двух недель с предыдущей статьи о портировании Bubbly Tap на Unity. Была проделана тяжелая работа, написано тонны кода, но главное, завершена геймплейная часть игры. Все что осталось - создать новый графический интерфейс, интегрировать необходимые сервисы и создать дополнительные уровни. (В общем, оставшейся работы еще на долго хватит :) )

Планы и их отсутствие

По мере разработки я столкнулся с неожиданным для себя фактом: я не составил никакого плана! Хотя в статье о самомотивации сам выделил важность планирования, но не последовал своим же советам. В голове возникло заблуждение: с переводом на новый движок можно справиться без плана. К сожалению это не так, даже наоборот - план при портировании продукта на другую технологию жизненно необходим. Есть огромная вероятность забыть что нибудь, не учесть и пропустить важное.

Спохватившись я завел проект в YouTrack, наоткрывав целую кучу тикетов. Потратил на это почти два дня. Но теперь мне легче работать, а график закрытых задач неумолимо ползет в верх. Это сильно греет сердце и самолюбие. Прогресс виден невооруженным глазом, даже когда дело касается архитектурной части.

Так же я внес для себя небольшое новшество - "ежедневный статус". Это документ в котором описывается прогресс по проекту за день. В нем нету особого смысла, я не перед кем не отчитываюсь, кроме "истории для потомков". Хотя... пост я пишу опираясь на данный документ, так что польза присутствует.

Редактор

Старая версия игры насчитывала 56 уровней записанных в одном огромном XML файле. В нем хранилось описание каждого узла-пузырика (положение на экране, тип, заполнен он или нет) и связей между ними. Продумывая строения нового уровня мне необходимо было нарисовать его на доске, протестировать там же, а после перенести в XML.

Из-за малого количества элементов простые уровни создавались легко и быстро. Когда дело дошло до сложных уровней, с большим количеством узлов и ребер, процесс создания превращался в настоящее испытание на внимательность и психическую устойчивость, занимающее большое количество сил и времени.

Simple level

Hard level

Текущую реализацию Bubbly Tap я собираюсь дополнить новыми задачками и переделать некоторые старые. Чтобы избежать прошлых мучений, я сразу сосредоточился на возможности изменять и создавать уровни прямо в редакторе Unity. Я не хотел делать лишней работы, для начала провел исследование на наличия подобных редакторов в Asset Store и на просторах GitHub. К сожалению, подходящих под игру наработок не нашлось. Механизм редактирования уровня пришлось создавать самому, перерабатывая архитектуру игры под новые нужды.

Теперь все, от положения узлов-пузырей на игровом поле, их текущего состояния, до связей между ними, можно контролировать прямо из редактора. А сами сущности уровней превратились в закрытые от внешнего мира "черные ящики", никак не связанные между собой или другими элементами игры.

Level editor

Строение уровней

Чтобы реализовать редактор Bubbly Tap была изменена концепция построения уровня, их внутренняя архитектура.

Уровень представляет из себя Ориентированный граф в котором пузырьки являются узлами графа, а стрелочки между ними это ребра графа. При нажатии на заполненный пузырек он заполняет своих соседей (связанные с ним узлы), сам при этом опустошается. Если заполняется уже заполненный узел, он лопается: пользователь проиграл. Цель игры - заполнить узлы "выхода", не переполнив при это другие.

Уровень в текущей реализации это игровой объект, представляющий из себя граф и содержащий игровые объекты узлов. Каждый узел содержит список своих соседей по которому автоматически строятся ребра. Если два узла содержат друг друга в списках соседей, то ребро для них будет двунаправленным (стрелочка указывает на оба пузыря), иначе ребро будет построено от одного узла к другому.

Edge direction

В этом графе у узел A в списке соседей B и C, у узла B в списке только A, а у C список и вовсе пуст. Между А и В построилось двунаправленное ребро, а между А и С ребро направленно в одно сторону, на узел С.

Ребра "привязанны" к своим узлам и всегда следуют за ними, поэтому если изменить положение одного из пузырьков на экране, ребро-стрелка автоматически станет на правильное место, изменит свой размер и наклон так чтобы указывать на свои узлы.

Ошибка в архитектуре

Практически закончив с разработкой геймплейной части Bubbly Tap я понял что допустил огромную и неприятную ошибку. Для контроля над уровнями был создан игровой менеджер, следящий за состоянием текущего уровня, и создававший новые уровни по мере необходимости. Проблема была в том, что менеджер и граф уровня были связаны друг с другом. Жесткая связь оказалась не только критическим просчетов в архитектуре, но и порождала неожиданные ошибки во время работы приложения, особенно при уничтожении объектов.

Пришлось потратить несколько дней и разорвать связи между игровыми менеджерами, графом уровня и менеджерами графических интерфейсов. Я сделал это с помощью простой реализации паттерна сигналов. Теперь граф уровня сам контролирует свое состояние, а в случае выигрыши или проигрыша он отсылает оповещение. Заинтересованные менеджеры "слушают" оповещение и реагируют на него, даже не зная от куда оно пришло. Например менеджер игр создает новый уровень, а менеджер GUI обновляет текстовое поле с индикатором уровня.

Non color подход

Кроме переработки архиектуры и создания редактора большое внимание я уделили визуальной части игры. Во первых, я переделал практически все анимации которые присутствовали в flash версии Bubbly Tap. Я ушел от подхода frame by frame, переделав анимации с помощью Unity аниматора, сделав их немного плавнее и чуть более экспрессивнее. Цель была достичь хорошего отклика и четкости анимации.

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

Old version (пузыри с пунктиром - узлы выхода)

Изменение состояния некоторых пузырей в старой версии обозначались изменением цвета. Например активный пузырь выхода от пассивного отличался только цветом, графическое обозначение оставалось неизменным. Это сильно путало некоторых игроков.

Я решил максимально избавиться от неясностей и для этого изменил иконки узлов. Теперь каждый узел в разных состояниях выглядят по разному и в игру можно играть даже в черно-белом режиме.

А вот и небольшая демонстрация: