Всем привет! Мы два новоиспеченных разработчика мобильных игр, бывшие одноклассники, выпускники Казанского федерального университета, Айдар и Эд.
Айдар: «История нашей игры «Syncomania» началась с того, что мне приснился странный сон. Он представлял собой компьютерную игру, где на квадратном поле синхронно передвигались четыре белых шарика. Когда первый из них вырвался за пределы игрового поля, я проснулся. Наутро я позвонил Эду, а уже в обед мы встретились во дворе университета, где я работал».
Эд: «Какой программист не мечтал сделать свою игру? Летом 2014-го у меня было много свободного времени, и я с радостью ухватился за эту идею. Тогда мы и представить себе не могли, с какими трудностями мы столкнемся».
Впрочем, на первом этапе мы были полны энтузиазма, все было легко и интересно. Именно о нем мы и расскажем в первой части статьи.
Итак, на входе у нас была одна простая идея — игрок одним движением управляет четырьмя героями.
Вначале нужно было разобраться с жанром игры. Аркады мы отклонили довольно быстро: управлять таким количеством одновременно движущихся элементов — задача не из легких. Нам обоим нравятся размеренные интеллектуальные игры, поэтому мы сошлись на том, что это будет пошаговая головоломка. Правда, пользователям от этого легче не стало — игра получилась хардкорной. Также мы решили исключить случайные и непредсказуемые элементы, чтобы процесс игры полностью зависел от действий игрока.
Эд: «Недолго думая, в качестве языка программирования я выбрал Processing, так как на нем легко создавать прототипы без предварительных настроек. Кроме того, синтаксис Java позволил нам без труда перенести логику игры на Android при помощи таких комбинаций, как Ctrl+C и Ctrl+V, но об этом позднее. Мы создали четырех героев в виде белых кругов и меняли их координаты с помощью стрелок на клавиатуре».
Айдар: «Начальное положение героев мы установили в равноудаленных местах уровня, так как это выглядело симметрично и “почему бы и нет?”. Впоследствии, мы решили, что будет прикольно, если каждый уровень будет начинаться так же».
Немного поэкспериментировав с управлением, мы поняли, что героям нужна цель, некий выход с уровня. Поначалу мы рассматривали идею вывести героев за пределы игрового поля (именно так было во сне Айдара). Но единственный выход показался нам интереснее и драматичнее — он накладывал больше ограничений (из которых, как известно, и рождается творчество). Так у нас появилось единственное условие победы: все герои должны выйти живыми. Табличку «выход» обычно подсвечивают зеленым цветом. Мы поступили так же.
![image](https://habrastorage.org/files/bc5/c58/e8b/bc5c58e8bfcd4384a197f34d5a4e0f1f.gif)
«На второй день Они создали стену. Да будет стена посреди уровня, и да отделит она героев от выхода».
Объект стена — это естественное препятствие и основной инструмент для построения сценария прохождения. Интуитивно мы решили, что герой остается на месте, если на пути его следования стоит стена. Так как стены обычно строят из камня, то мы изобразили их как серый квадрат.
![image](https://habrastorage.org/files/372/727/b41/372727b41bb84bbb9a43646a632c8d9a.gif)
Игровое поле мы составили в виде шахматной доски размерностью 11 на 11. Таким образом проще хранить и перемещать объекты. Например, если герой находится в левом нижнем углу, то его координаты — [0][0]. Чтобы подвинуть героя на одну клетку вверх, достаточно прибавить единицу к значению строки: [0+1][0]=>[1][0]. Каждую клетку может занимать только один объект, из чего вытекает естественный вопрос: «Что произойдет, если два объекта окажутся на одной клетке?» Впервые мы над этим задумались, только когда один герой уперся в стену, а второй на него наехал. Так появилось одно из условий проигрыша: два героя на одной клетке взаимно уничтожаются.
![image](https://habrastorage.org/files/c32/b48/771/c32b487710944e1185f35caff1cfd5bc.gif)
Еще одно условие проигрыша появилось, когда мы создали элемент ловушка — клетка, при попадании на которую герой умирает. Ловушку нужно было изобразить как что-то опасное и запретное, поэтому, придерживаясь минималистичного стиля, мы выбрали красный квадрат.
![image](https://habrastorage.org/files/7e7/bc5/2e0/7e7bc52e081646d1aa66cf1918470ad7.gif)
Эд:«Мне очень нравится настольная игра «Роборалли», и в особенности система конвейеров, которая вносит элемент неожиданности, если неверно рассчитать свои действия. Конвейеры срабатывают в отдельной фазе хода (после передвижения героев) и смещают объекты по направлению стрелки. В нашу игру мы привнесли нечто подобное, назвав это потоками».
Потоки имеют две основные функции:
1) Система ниппель. Она пропускает в одну сторону, но не пропускает обратно.
![image](https://habrastorage.org/files/fd5/2c2/a0b/fd52c2a0bfa445ebbe02d1036ae9a7ed.gif)
2) Поточная линия. С помощью нее герои, враги и ящики (о них чуть позже) могут кататься по предустановленным маршрутам.
![image](https://habrastorage.org/files/485/a63/304/485a633048c54425a8db22cc34d7c0eb.gif)
Айдар: «Продолжая поиск изощренных способов убить героев, мы решили развить идею ловушек и сделать их подвижными. Сначала у нас была мысль ввести в игру ловушку-маятник, которая с определенной частотой перемещалась бы между двумя клетками. Но ловушка, которая может путешествовать по всему игровому полю — это намного круче. Такие элементы получаются “живыми”, и мы сразу же назвали их врагами».
Однако беспорядочное перемещение элементов вносит в игру непредсказуемость и неконтролируемость, которые идут вразрез с законами придуманного нами мира. Поэтому мы приняли решение, что враги должны управляться самим игроком и, будучи антагонистами героев, двигаться наперекор командам, то есть в обратную сторону. Например, если герой идет направо, то враг — налево.
![image](https://habrastorage.org/files/d64/c4e/624/d64c4e6245984d6988c35d3c68f22ee0.gif)
Когда врагов на уровне достаточно много, создается иллюзия, что они живут своей жизнью: катаются в потоках, безуспешно бьются головой о стены, погибают в ловушках или объятьях друг друга, покидают этот мир через выход и, как будто специально (на самом деле нет), все время пытаются убить героев.
![image](https://habrastorage.org/files/e93/6d7/008/e936d7008c4740ebac4a127bdd88ba31.gif)
Эд: «На одном из тестовых уровней враги так раздражали, что мне все время хотелось им отомстить. Нужен был инструмент, а точнее оружие против них, которым могли бы воспользоваться герои. Перебрав несколько вариантов, мы решили давить врагов тяжелыми предметами».
Мы вспомнили игру «Сокобан» и создали модифицированный вид ящиков (новое — это хорошо забытое старое). По сути, ящики — это стены, которые можно толкать, поэтому мы изобразили их как уменьшенные серые квадраты с перекрестием. Они гармонично вписались в правила нашей игры: если толкнуть ящик на клетку с героем или врагом, то персонажи умирают, так как по закону два объекта не могут находиться в одной клетке. Кроме того, ящики могут ездить в потоках, а при попадании в ловушку или выход они разрушаются. Как и в игре «Сокобан», нельзя толкать больше одного ящика в ряд, поэтому возможны ситуации, когда герой оказывается взаперти.
![image](https://habrastorage.org/files/095/dd1/f6e/095dd1f6e8a24f098ce43e2d820d1c39.gif)
Айдар: «При создании уровня предугадать все возможные решения практически невозможно, и уже в самом начале мы с Эдом заметили, что проходим уровни по-разному. Это неудивительно, ведь с каждым новым ходом число состояний растет экспоненциально».
Вариативность прохождения — это особенность игры, которой мы искренне гордимся. Конечно, большинство уровней возможно пройти не задумываясь, но тогда вместо двадцати ходов вам может понадобиться сорок или шестьдесят. Так в игре появился стимул к повторному прохождению — поиск кратчайшего решения.
Эд: «Лично для меня поиск оптимального прохождения — это любимая часть в игре. В самом начале разработки мы завели таблицу, где наши друзья, самые первые пользователи, делились своими рекордами: за сколько ходов был пройден уровень. Бить рекорды и попадать в этой список мотивировало нас играть дальше».
Перед релизом игры нам понадобилось собрать кратчайшие прохождения всех уровней, чтобы выдавать их в виде платных подсказок. Для этого мы запрограммировали алгоритм перебора с ограничениями, но он работал чересчур долго на уровнях с большим количеством объектов. Когда время расчетов превысило несколько суток, мы решили воспользоваться краудсорсингом (англ. crowdsourcing, crowd — «толпа» и sourcing — «использование ресурсов»). Если игрок улучшал рекорд на одном из уровней, то с помощью Google Analytics мы получали его решение в виде последовательности ходов. Опытные игроки обычно ищут оптимальное прохождение эвристически, применяя свои наработанные шаблоны и избегая избыточных ходов. Таким образом, мы быстро пополнили базу прохождений, но, к нашему удивлению, некоторые игроки до сих пор продолжают бить рекорды. Их мы аккуратно записываем и обновляем в последующих версиях приложения.
![image](https://habrastorage.org/files/809/653/ba0/809653ba03964e5bb6eea029fc93de59.gif)
Продолжение следует…
В следующей части мы расскажем о том, как разрабатывали загадки и технику прохождения уровней в игре «Syncomania».
Как мы придумали и сделали свою первую игру на Android. Часть 2: Уровни
Айдар: «История нашей игры «Syncomania» началась с того, что мне приснился странный сон. Он представлял собой компьютерную игру, где на квадратном поле синхронно передвигались четыре белых шарика. Когда первый из них вырвался за пределы игрового поля, я проснулся. Наутро я позвонил Эду, а уже в обед мы встретились во дворе университета, где я работал».
Эд: «Какой программист не мечтал сделать свою игру? Летом 2014-го у меня было много свободного времени, и я с радостью ухватился за эту идею. Тогда мы и представить себе не могли, с какими трудностями мы столкнемся».
Впрочем, на первом этапе мы были полны энтузиазма, все было легко и интересно. Именно о нем мы и расскажем в первой части статьи.
Итак, на входе у нас была одна простая идея — игрок одним движением управляет четырьмя героями.
Вначале нужно было разобраться с жанром игры. Аркады мы отклонили довольно быстро: управлять таким количеством одновременно движущихся элементов — задача не из легких. Нам обоим нравятся размеренные интеллектуальные игры, поэтому мы сошлись на том, что это будет пошаговая головоломка. Правда, пользователям от этого легче не стало — игра получилась хардкорной. Также мы решили исключить случайные и непредсказуемые элементы, чтобы процесс игры полностью зависел от действий игрока.
Эд: «Недолго думая, в качестве языка программирования я выбрал Processing, так как на нем легко создавать прототипы без предварительных настроек. Кроме того, синтаксис Java позволил нам без труда перенести логику игры на Android при помощи таких комбинаций, как Ctrl+C и Ctrl+V, но об этом позднее. Мы создали четырех героев в виде белых кругов и меняли их координаты с помощью стрелок на клавиатуре».
Айдар: «Начальное положение героев мы установили в равноудаленных местах уровня, так как это выглядело симметрично и “почему бы и нет?”. Впоследствии, мы решили, что будет прикольно, если каждый уровень будет начинаться так же».
Немного поэкспериментировав с управлением, мы поняли, что героям нужна цель, некий выход с уровня. Поначалу мы рассматривали идею вывести героев за пределы игрового поля (именно так было во сне Айдара). Но единственный выход показался нам интереснее и драматичнее — он накладывал больше ограничений (из которых, как известно, и рождается творчество). Так у нас появилось единственное условие победы: все герои должны выйти живыми. Табличку «выход» обычно подсвечивают зеленым цветом. Мы поступили так же.
![image](https://habrastorage.org/files/bc5/c58/e8b/bc5c58e8bfcd4384a197f34d5a4e0f1f.gif)
«На второй день Они создали стену. Да будет стена посреди уровня, и да отделит она героев от выхода».
Объект стена — это естественное препятствие и основной инструмент для построения сценария прохождения. Интуитивно мы решили, что герой остается на месте, если на пути его следования стоит стена. Так как стены обычно строят из камня, то мы изобразили их как серый квадрат.
![image](https://habrastorage.org/files/372/727/b41/372727b41bb84bbb9a43646a632c8d9a.gif)
Игровое поле мы составили в виде шахматной доски размерностью 11 на 11. Таким образом проще хранить и перемещать объекты. Например, если герой находится в левом нижнем углу, то его координаты — [0][0]. Чтобы подвинуть героя на одну клетку вверх, достаточно прибавить единицу к значению строки: [0+1][0]=>[1][0]. Каждую клетку может занимать только один объект, из чего вытекает естественный вопрос: «Что произойдет, если два объекта окажутся на одной клетке?» Впервые мы над этим задумались, только когда один герой уперся в стену, а второй на него наехал. Так появилось одно из условий проигрыша: два героя на одной клетке взаимно уничтожаются.
![image](https://habrastorage.org/files/c32/b48/771/c32b487710944e1185f35caff1cfd5bc.gif)
Еще одно условие проигрыша появилось, когда мы создали элемент ловушка — клетка, при попадании на которую герой умирает. Ловушку нужно было изобразить как что-то опасное и запретное, поэтому, придерживаясь минималистичного стиля, мы выбрали красный квадрат.
![image](https://habrastorage.org/files/7e7/bc5/2e0/7e7bc52e081646d1aa66cf1918470ad7.gif)
Эд:«Мне очень нравится настольная игра «Роборалли», и в особенности система конвейеров, которая вносит элемент неожиданности, если неверно рассчитать свои действия. Конвейеры срабатывают в отдельной фазе хода (после передвижения героев) и смещают объекты по направлению стрелки. В нашу игру мы привнесли нечто подобное, назвав это потоками».
Потоки имеют две основные функции:
1) Система ниппель. Она пропускает в одну сторону, но не пропускает обратно.
![image](https://habrastorage.org/files/fd5/2c2/a0b/fd52c2a0bfa445ebbe02d1036ae9a7ed.gif)
2) Поточная линия. С помощью нее герои, враги и ящики (о них чуть позже) могут кататься по предустановленным маршрутам.
![image](https://habrastorage.org/files/485/a63/304/485a633048c54425a8db22cc34d7c0eb.gif)
Айдар: «Продолжая поиск изощренных способов убить героев, мы решили развить идею ловушек и сделать их подвижными. Сначала у нас была мысль ввести в игру ловушку-маятник, которая с определенной частотой перемещалась бы между двумя клетками. Но ловушка, которая может путешествовать по всему игровому полю — это намного круче. Такие элементы получаются “живыми”, и мы сразу же назвали их врагами».
Однако беспорядочное перемещение элементов вносит в игру непредсказуемость и неконтролируемость, которые идут вразрез с законами придуманного нами мира. Поэтому мы приняли решение, что враги должны управляться самим игроком и, будучи антагонистами героев, двигаться наперекор командам, то есть в обратную сторону. Например, если герой идет направо, то враг — налево.
![image](https://habrastorage.org/files/d64/c4e/624/d64c4e6245984d6988c35d3c68f22ee0.gif)
Когда врагов на уровне достаточно много, создается иллюзия, что они живут своей жизнью: катаются в потоках, безуспешно бьются головой о стены, погибают в ловушках или объятьях друг друга, покидают этот мир через выход и, как будто специально (на самом деле нет), все время пытаются убить героев.
![image](https://habrastorage.org/files/e93/6d7/008/e936d7008c4740ebac4a127bdd88ba31.gif)
Эд: «На одном из тестовых уровней враги так раздражали, что мне все время хотелось им отомстить. Нужен был инструмент, а точнее оружие против них, которым могли бы воспользоваться герои. Перебрав несколько вариантов, мы решили давить врагов тяжелыми предметами».
Мы вспомнили игру «Сокобан» и создали модифицированный вид ящиков (новое — это хорошо забытое старое). По сути, ящики — это стены, которые можно толкать, поэтому мы изобразили их как уменьшенные серые квадраты с перекрестием. Они гармонично вписались в правила нашей игры: если толкнуть ящик на клетку с героем или врагом, то персонажи умирают, так как по закону два объекта не могут находиться в одной клетке. Кроме того, ящики могут ездить в потоках, а при попадании в ловушку или выход они разрушаются. Как и в игре «Сокобан», нельзя толкать больше одного ящика в ряд, поэтому возможны ситуации, когда герой оказывается взаперти.
![image](https://habrastorage.org/files/095/dd1/f6e/095dd1f6e8a24f098ce43e2d820d1c39.gif)
Айдар: «При создании уровня предугадать все возможные решения практически невозможно, и уже в самом начале мы с Эдом заметили, что проходим уровни по-разному. Это неудивительно, ведь с каждым новым ходом число состояний растет экспоненциально».
Вариативность прохождения — это особенность игры, которой мы искренне гордимся. Конечно, большинство уровней возможно пройти не задумываясь, но тогда вместо двадцати ходов вам может понадобиться сорок или шестьдесят. Так в игре появился стимул к повторному прохождению — поиск кратчайшего решения.
Эд: «Лично для меня поиск оптимального прохождения — это любимая часть в игре. В самом начале разработки мы завели таблицу, где наши друзья, самые первые пользователи, делились своими рекордами: за сколько ходов был пройден уровень. Бить рекорды и попадать в этой список мотивировало нас играть дальше».
Перед релизом игры нам понадобилось собрать кратчайшие прохождения всех уровней, чтобы выдавать их в виде платных подсказок. Для этого мы запрограммировали алгоритм перебора с ограничениями, но он работал чересчур долго на уровнях с большим количеством объектов. Когда время расчетов превысило несколько суток, мы решили воспользоваться краудсорсингом (англ. crowdsourcing, crowd — «толпа» и sourcing — «использование ресурсов»). Если игрок улучшал рекорд на одном из уровней, то с помощью Google Analytics мы получали его решение в виде последовательности ходов. Опытные игроки обычно ищут оптимальное прохождение эвристически, применяя свои наработанные шаблоны и избегая избыточных ходов. Таким образом, мы быстро пополнили базу прохождений, но, к нашему удивлению, некоторые игроки до сих пор продолжают бить рекорды. Их мы аккуратно записываем и обновляем в последующих версиях приложения.
![image](https://habrastorage.org/files/809/653/ba0/809653ba03964e5bb6eea029fc93de59.gif)
Продолжение следует…
В следующей части мы расскажем о том, как разрабатывали загадки и технику прохождения уровней в игре «Syncomania».
Как мы придумали и сделали свою первую игру на Android. Часть 2: Уровни