Что такое Ångström Style System (ÅSS)? Это вторая версия библиотеки стилей для нативных приложений iOS, которую написал Шурик Бабаев (@bealex). Недавно появилась новая версия на Swift, которая называется S2, но мы её ещё не успели попробовать, поэтому я расскажу про реальное использование ÅSS на одном из наших текущих проектов.
Ура! Игра!
Я занимаюсь разными игровыми проектами. В процессе создания каждой игры требуется настройка игрового дизайна, учитывать приходится огромное количество нюансов. Если вы также ведёте разработку «PvZ-inspired» игры, то вам будет необходимо продумать, как эффективно организовать настройки. Как? Читайте дальше.
- поле — экран iPhone (iPad);
- два игрока: один «сверху», другой «снизу», у каждого есть «домик»;
- у каждого игрока есть «лента», на которой появляются игровые объекты двух типов: защитные и атакующие;
- игрок перетаскивает игровые объекты на поле, они начинают «жить»; атакующие — либо идут вперёд/атакуют, либо стоят и стреляют, защитные как-то защищаются; если защиты не осталось, то стреляют по домику, и когда домик разваливается — игрок проигрывает.
В такой игре достаточно трудно быстро и качественно проработать баланс. Игровых объектов обычно десятка два, у каждого есть набор базовых параметров (скорость атаки, сила атаки, защита, скорость передвижения, количество единиц здоровья, прочее) и, может, какие-то специфические параметры (количество маны, коэффициент удачи, прочее), каждый объект может быть поставлен в любое (или нет) место экрана и общая схема выходит очень сложной.
Чтобы разобраться во всех этих параметрах, необходимо иметь возможность быстро их менять. Причём не только их, но и какие-то тестовые конфигурации. Например, проверяем, могут ли два атакующих объекта завалить один защитный (и как быстро). Подобрали параметры, запустили приложение, поставили два объекта тут, один там… долго. Нужно быстрее. Приятно, если можно:
- загрузить приложение сразу с тестовой конфигурацией;
- чтобы приложение скачивало параметры игровых объектов из внешнего ресурса;
- применить, протестировать (может быть, даже без анимации, чтобы ещё быстрее было);
- показать нужный результат, получить «аппрув»;
Такая логика даёт возможность быстро тестировать игровой баланс, настраивать разные параметры. А если сюда привязать ещё и квантифицируемые задачи (настроить параметры так, чтобы статистически получился баланс типа «камень-ножницы-бумага», например, и менять параметры (генерировать конфиг) автоматически, то можно как настроить баланс, так и перестраивать его при необходимости автоматически.
Для ускорения работы (и прочие параметры эффективного труда) нам удобно использовать ÅSS.
Пример работы с ÅSS для настройки игровых параметров
Итак, что нам требуется от системы, которая будет загружать игровые параметры?
- возможность загрузки данных из стороннего файла;
- обновление без перезапуска приложения;
- удобная работа, подключение стилей в приложении.
Рассмотрим на примере простого файла, дальше его масштабировать можно сколь угодно. В файле я задаю параметры самой игры, и для нескольких игровых объектов, файл можно назвать styles_game.json:
{
"debug": {
"level": "GMDebugLevelAll",
"gameSpeed": 100,
}
"game": {
"objects": [
{
"id": "Attacker 1",
"speed": 1,
"attack": 2,
"defence": 0.5,
"health": 100
},
{
"id": "Defence 1",
"speed": 0,
"attack": 0,
"defence": 2.5,
"health": 1000
}
],
"parameters": {
"linesCount": 5,
"lineLength": 30
}
}
}
Чтобы этот файл можно было выложить на сервер, нужно создать основной файл стилей, который мы назовём styles_main.json:
{
"@include.game": {
"inApp": "styles_main.json",
"remote": "https://cdn.server.com/styles_main.json"
}
}
После чего настроим ÅSS в приложении. Подробности о том, как это сделать — в блоге разработчика библиотеки (@bealex), тут я предполагаю, что то, что сказано в той статье, в разделе «Работа со стайлером», выполнено. Перейдём к специфическим для моего применения частям.
Автообновление
В статье только мельком указана замечательная особенность ÅSS — возможность обновления «на лету». Мы для своих проектов всегда делаем кнопку «обновить стили» либо в меню, либо прямо на экране (если обновление очень-очень частое). Можно привязать и к какому-либо жесту, но, поскольку мы создаём игры, жесты часто используются в игровом процессе, и дебажная кнопка гораздо проще/удобнее. Итак, автообновление. Чтобы его подключить, нужно написать что-то такое:
MyGameSettings *style = [[MyGameSettings alloc]
initWithStyleReloadedCallback:
^{
[self updateGameSettings];
}];
А к кнопке привязываем код:
ASStyler *styler = [ASStyler sharedInstance];
[styler reloadStylesFromURL:@"styles_main.json"];
В результате, каждый раз, когда пользователь нажимает на кнопку, стили обновляются и после обновления (и скачивания удалённого файла), вызывается код updateGameSettings, где нужно аккуратно обновить параметры всех объектов, и перезапустить игру (или продолжить текущую).
Выводы
ÅSS — хорошее решение для работы с конфигурациями. Я попробовал несколько других решений, но некоторые из них привязаны к визуальным стилям (например, те, которые про CSS), другие (как DB5) требуют пересборки приложения, что замедляет разработку.
Также такого рода система очень помогает в распределённой команде, или в любой другой команде, где гейм-дизайнер сидит отдельно от разработчика. Разработчик делает тестовую сборку, выдаёт гейм-дизайнеру и продолжает разрабатывать, в это же время гейм-дизайнер развлекается с настройками параметров объектов, подыскивая идеальный баланс. Если ему требуется ещё несколько параметров — он просит разработчика, чтобы тот подключил их.
Автор: aliakseipashkel