Gamedev
Cyberslav
4889

Система частиц для игры в стиле ASCII-art

Система частиц — распространённый способ создания эффектов вроде огня, взрывов, дыма и так далее. В этой статье я расскажу, как разработал систему частиц для своей игры Unsigned Character, выполненной в стиле ASCII-art.

В закладки
Слушать

Цель: разработать универсальную систему частиц для эффектов пламени, взрыва, шлейфа от снарядов и так далее.

Частицы должны имитировать статичное пламя, а также формировать след за движущимся объектом. Вся графика в игре состоит из символов. Поэтому частицы тоже должны рисоваться символами. И разработать это придётся с нуля. В качестве вдохновения я использовал эти анимации из игры asciident:

1. Поток частиц

Я начал с простого. Частицы спавнятся в фиксированной точке. С некоторым интервалом они поднимаются на строку вверх и рандомно сдвигаются по горизонтали (от -1 до 1 символа). Попутно на каждом уровне (строке) выбирается нужный цвет и рандомный символ из заданного набора для этого уровня.

Распределение цветов и вариантов символа по уровням выглядело как-то так:

private static String _frameVariants[] = { "&@0", "&0", "o0*", "o*'", "*.,", "., ", ". ", ". " }; private static FormattedCharacter.Color _frameColors[] = { FormattedCharacter.Color.White, FormattedCharacter.Color.LightYellow, FormattedCharacter.Color.Yellow, FormattedCharacter.Color.Gray, FormattedCharacter.Color.Gray, FormattedCharacter.Color.Gray, FormattedCharacter.Color.Gray, FormattedCharacter.Color.Gray, };

2. Синхронизация потоков

Далее хочется получить более «объёмное» пламя. Поэтому спавним несколько частиц за раз (по умолчанию 3).

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

Отдалённо напоминает пламя, но выглядит как-то топорно. Если присмотреться к анимации из аскидента, то можно заметить, что частицы там проигрывают некоторую анимацию прежде чем подняться на следующий уровень. Самое время добавить это в проект.

3. Анимация частиц

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

Заодно, я вынес конфигурацию эффектов в json. Вот так выглядит единый набор анимаций частиц:

"animations": [ ".oO0@*", "o0@*", "o&*", ".o&*", "o*'", ".o", ".c*'", ".*", ".,'", ".'", ".' ", ".", ".", " " ],

Каждая строка формирует последовательность «кадров». Можно заметить, что анимации изображают частицу, движущуюся вверх. Из нижнего положения (. или o) в верхнее (* или ').

4. Движение за объектом

У нас есть пламя со статичным источником. Теперь хочется, чтобы источник мог двигаться. В игре физические объекты могут двигаться попиксельно. Их координаты не привязаны к символьной сетке. Но для частиц это недопустимо. Если частицы не будут выровнены по сетке, они будут перекрываться друг с другом, что сильно испортит эффект. Поэтому частицы всегда спавнятся и движутся по символьным координатам. Это создаёт некий рассинхрон. Место спавна частиц не точно совпадает с источником пламени, но это не критично.

Другая проблема — при быстром движении источника огненный след получается очень редким. Решение — спавнить внеочередную частицу в момент, когда источник пламени меняет символьные координаты (строка/столбец).

Если раньше источник был в одном символе, а теперь в другом — спавним в новом месте новую частицу не дожидаясь, когда придёт время обычного спавна. И не просто спавним, а рандомно с заданной вероятностью. Эта вероятность зависит от количества потоков, то есть количества частиц, которое спавнится обычным образом (в пункте 2 мы дали этой величине значение по умолчанию 3).

Кроме того делаем дополнительные модификации, чтобы огонь в движении выглядел реалистичнее.

4.1. Длительность кадра

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

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

4.2. Вероятность подъёма

С ускорением «кадров» частицы начинают быстрее подниматься и формируют более размытый след. Чтобы избежать этого, я немного переделал движение частиц. Теперь при смене кадров они поднимаются не всегда, а рандомно с некоторой вероятностью. Вероятность эта равна 0 на самом первом уровне и поднимается до 1 на самом последнем.

Кроме того, перед подъёмом и сдвигом частицы проверяется пересечение с картой. Частицы не заходят на статичные занятые области уровня.
В итоге получился такой результат:

Этого факела нет в игре, но он отлично демонстрирует работу системы частиц

5. Затухающее пламя

Небольшая модификация позволит сделать пламя, которое разгорается по команде и затухает со временем. Достаточно уменьшать количество потоков (которое до этого всё время было равно 3) и задавать начальное смещение кадра.

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

6. Одноразовый спавн частиц

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

В этом взрыве также создаются два невидимых физических объекта, со своими системами частиц.

7. Ссылки

{ "author_name": "Cyberslav", "author_type": "self", "tags": ["\u043e\u043f\u044b\u0442","\u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f"], "comments": 31, "likes": 306, "favorites": 206, "is_advertisement": false, "subsite_label": "gamedev", "id": 141023, "is_wide": false, "is_ugc": true, "date": "Sat, 30 May 2020 04:29:36 +0300", "is_special": false }
0
31 комментарий
Популярные
По порядку
Написать комментарий...

Атомный блик

37

Ох, шикарно. Если честно, глядя на эти гифки, впервые захотелось поиграть в ASCII игру.

Ответить
2

Dwarf fortress в помощь)

Ответить
12

Зачем ты с ним так жестоко?

Ответить
0

Stone story или как там называется...

Ответить
0

Dugeon Crawl Stone Soup?

Ответить
0

Welcome to the club, buddy

Ответить
6

Это ж гениально, блин.

Ответить

Комментарий удален

1

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

Ответить
3

Игра уже есть. Отдалённо напоминает пещеру с необычной растительностью.

Ответить
1

Используй 

Ответить
0

В какой-то степени согласен с тобой. С другой стороны не понятно какова у разработчика цель: создать игру с реалистичными эффектами и интуитивно понятным окружением нарисованным таким, казалось бы, неточным инструментом, что позволит сыграть на контрасте, или же достичь максимальной абстракции. Думаю что в первом случае игра смотрелась бы будто бы материальной - накинуть эффектов свечения на огонь, попробовать реализовать тени, добавить звуков, таких, чтоб сразу было ясно с каким материалом ты взаимодействуешь. Эффектов окружения типа эхо в пещерах и эмбиента. Я хз, но возможно это смотрелось бы просто потрясающе. А возможно я просто ебанулся на теме The Last Night

Ответить
1

За реализмом я не гонюсь. Эффектов освещения не будет, потому что у меня палитра из 16 цветов. Просто накинул систему частиц, что бы выглядело по-живее. А по поводу освещения рекомендую ознакомиться с ASCIIDENT.

Ответить

Ложный яд

2

Выглядит очень круто! Ябсыграл.

Ответить
1

Скачала, зарейтила, надеюсь всё-таки будешь развивать и наполнять контентом понемногу. 

Ответить
1

Теперь я знаю, чего не хватает в документации юнити

Ответить
1

Это же шедевр! 
Люблю и чту ASCII и рогалики)

Ответить
0

Когда игра вылет на пк?

Ответить
1

Релиз на ПК не планирутеся, но есть общедоступные сборки. Лежат здесь: https://yadi.sk/d/hZ-SJLnvT-oEvw

Ответить
0

Крутая стилистика! Добавил в список желаемого стим

Ответить
0

Скачиваю со стора

Ответить
0

Круто-круто

Ответить
0

В интересное время живём. А до чего прогресс при наших внуках дойдёт - представить страшно.

Ответить
0

Ты крутой, давно слежу за твоим творчеством)

Ответить

Иностранный хот-дог

0

Лень читать, но выглядит оч круто!

Ответить
0

Хорошие патиклы - отрада для любого сердца!

Ответить
0

Никогда не понимал, как у людей получается придумывать рисунки из этих символов

Ответить
0

Очень круто! Только лично мне кажется, что символ & в огне лишний, он слишком привлекает внимание и массивный по сравнению с другими частичками.

Ответить
0

Может быть, но он нужен для разнообразия. Если разных вариантов мало, огонь выглядит хуже.

Ответить
0

Очень необычно! 🤩👍

Ответить

Комментарий удален

0

Неиронично советую найти и скачать игру Гульмен против Монстров и покопаться, там lowres спрайты каким то бесовским алгоритмом конвертируются в ASCII и в итоге это 3D игра с открытым миром и разрушаемостью террейна в текстовом графоне.

Ответить
0

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

Ответить

Комментарии

{ "jsPath": "/static/build/dtf.ru/specials/DeliveryCheats/js/all.min.js?v=05.02.2020", "cssPath": "/static/build/dtf.ru/specials/DeliveryCheats/styles/all.min.css?v=05.02.2020", "fontsPath": "https://fonts.googleapis.com/css?family=Roboto+Mono:400,700,700i&subset=cyrillic" }