Постмортем Hold The Fort!. Часть 2 – Графика и звук
В микропосте со ссылкой на первую часть рассказа о создании игры «Hold The Fort!» на мой призыв остановить меня лопатами никто не ответил, поэтому вот вам полноценный пост-продолжение. Первая часть была посвящена дизайну и коду, а теперь про графику и звук.
На скриншоте слева направо: бесёнок, ротозей, обезьяна, жаба, улей и пятачок.
Графика
Рисовать я не никогда не умел, но всегда любил. Когда пришла пора заниматься внешним видом игры, я сдул пыль с древнего графического планшета Wacom Intuos 2 и принялся за дело.
Простые элементы, вроде травы, камней или панелей меню, я рисовал сразу. Монстров, лучников и прочие сложные штуки рисовал на бумаге (к сожалению, скетчи куда-то подевал, не могу найти), сканировал, обводил в Photoshop, резал на составные части в Adobe Flash и анимировал. Графику экспортировал в swc, а затем внедрял в игру и переводил в растр через пару классов для работы с анимацией, позаимствованные из ранних версий движка Anthill Антона Карлова.
На этапе прототипа я не заморачивался с графикой, по экрану скакали кружочки и квадратики. Когда же движок был готов, и стало понятно, что уже сильно ничего не поменяется, нарисовал чистовик. Ниже картинки «было-стало», февраль 2014-октябрь 2015.
01)
Итог по графике:
Рисовать и анимировать мне понравилось. Графический планшет гораздо более удобен, чем мышь, но даже с ним рисование заняло больше трети времени работы над игрой. Результат превзошёл первоначальные ожидания, поэтому, прикусив перфекционизм, я смирился с тем, что получилось.
Вот парочка отличных книг по рисованию и анимации:
- Тайминг в анимации. Гарольд Уайтэкер, Джон Халас
- Ключи к искусству рисунка. Берт Додсон
Звук
За три месяца до завершения работы над игрой у меня всё ещё не было ни звуков, ни музыки. «Ну и ладно, фиг с ними!» — подумал я, — «Тем более, на их запись и внедрение у меня уйдёт ещё месяц». Но потом меня привёл в чувства комментарий на форуме: «Если звук требует месяца трудов — он чертовски нужен такой игре». В итоге я провозился больше месяца, но остался доволен результатом, но ещё больше – процессом.
«Раз уж взялся всё делать самостоятельно, то и звук нужно записывать самому» – решил я. Вооружившись старым mp3 плеером iriver T30 с функцией диктофона, я запирался в ванной и записывал разные звуки: визжал, кряхтел, рычал, долбил тазом по стене, стучал вилкой по батарее, в общем, как только не радовал соседей! Таким образом записал 3/4 всех звуков.
Вот несколько звуков из игры:
СЛУШАТЬ НА SOUNDCLOUD (минутный трек)
Особенно весело было озвучивать монстров. Неудивительно, что после рисования, программирования и озвучки персонажей игры я испытывал к ним почти отеческие чувства.
Музыку записывал так же: в ванной с диктофоном. А потом сводил и накладывал эффекты в Audition 3.0. Вся музыка записана исключительно при помощи инструментов, все из которых на фото:
03) На фото: самодельный диджериду, гитара, балалайка, думбек, флейта, 2 глиняных свистульки (одна Скопинская, вторая самодельная), шейкер, большой и малый варганы Павла Поткина
Итог по звуку:
Не пожалел, что решил заморочиться по звукам и музыке – это была самая весёлая часть работы над игрой. Со звуком стало гораздо лучше. Жаль только, что для экономии места я сохранил все файлы с битрейтом 56-96кбит/с, а более качественные варианты не сохранил.
Вот весь саундтрек к игре:
СЛУШАТЬ НА SOUNDCLOUD
- 27 мая 2016, 16:58
- 012
Времени прочитать пост нет, но за длинный пост поставлю мечик. В свободное время почитаю. И вообще где комментарии? Мечи есть а комментариев нет, ну что-ж буду первооткрывателем, флаг мне в руки. И музыка просто класс.
Богато так! И на коленке всё. Похвально.
Прошёл не отрываясь. Часа 3 заняло открыть всех героев. Игра А класс!
Спасибо! Рад, что понравилось.
В смысле, "открыть всех героев"? Прокачал всех лучников до героя или открыл все варианты перков?
Прокачал 8 лучников, чтобы посмотреть все 8 специализаций, из которых выбираешь при повышении до героя. До босса было 5 героев, ещё двух прокачал в бесконечном режиме. 5 челов оставил крестьянами, поэтому последний перк (строителя) открыл в новой игре. Смекнул, что у первого выживающего уже есть значительная прокачка.
Генерация имён тоже очень порадовала, запоминающиеся персонажи получаются: Йон Егерь, Глеб Дипломат, Эрик Лютый.
Круто! Я и не надеялся, что кто-то будет играть специально, чтобы открыть неоткрытые перки, но бесконечный режим сделал исключительно на этот случай. Выходит, не зря. Спасибо!
Кстати, прозвища тоже выдаются произвольно из нескольких вариантов, чтобы у лучников с одинаковыми перками были разные прозвища
Спасибо разработчику 7-11, за возможность продолжить игру после окончания обязательной части)
А ещё прочитал остальные статьи, но про технические детали, расчёт коллизий, борьбу с тормозами ничего не написано, а так хотелось посмотреть. Хотя в принципе понятно что стандартными способами. Но вдруг было найдено что-то новое, преодолены не очевидные проблемы?
Про техническую часть можно очень долго писать. Напишу тут вкратце.
С тормозами боролся так:
1. Всю графику в растр
2. Все ссылки на экземпляры классов чистить сразу после того, как экземпляр больше не нужен, на сборщик мусора не полагаться. Завести себе правило: если объект создан, его нужно потом удалить
3. То же самое со слушателями. Если слушатель создан, он должен быть удалён, как только перестаёт быть нужным
4. У классов по возможности заводить методы init и cleanup. В последнем чистить всех детей. Если у детей есть свои дети, во время чистки перед удалением ссылки на ребёнка запускать чистку самого ребёнка.
5. Как можно реже создавать экземпляры через new, особенно в циклах
6. Для множества одинаковых объектов использовать пулы
На самом деле, достаточно просто почитать пару-тройку статей по оптимизации и писать код с самого начала в соответствии с ними, и всё будет летать.
Коллизии рассчитывались чаще всего стандартным htTestPoint. Если враг был сложный и двигался (например, обезьяна - у ней и форма сложная, и крыльями она машет), для него создавалась круглая невидимая маска. В этом случае у стрелы сначала проверялось столкновение с врагом, а потом столкновение с его маской. В результате попадание в хобот или крылья обезьяне не засчитывалось - только в тело. Возможно, это не совсем реалистично, но нечестным не выглядит.
Основная проблема была в туннельном эффекте (если я правильно его называю и понимаю). Когда стрела летит быстро, то за кадр она может успеть пролететь сквозь препятствие, тогда столкновение не засчитается. Рассчитывать каждый кадр расстояние до препятствия и сравнивать его с тем расстоянием, которое стрела пролетит в течение следующего кадра, очень затратно, поэтому этот момент я регулировал подбором размера масок. Но не всем врагам подходила круглая маска, а рисовать сложную форму геморно. В этом случае (как, например, с боссом) я поступал так: присваивал врагу его же уменьшенное изображение как маску. В итоге попадание стрелы засчитывалось не в момент касания ею края врага, а когда она как быдто бы уже вонзилась в него поглубже.
Изначально у меня стрелы оставались воткнутыми во врагов. Пока враги не были анимированы, выглядело круто, особенно с сильными врагами - они были похожи на ёжиков. Но анимация у меня не программная, поэтому, когда враг шевелится, а стрела нет - выглядит некрасиво. Так что втыкание стрел во врагов я убрал.
Что касается необычного решения неочевидных проблем, делая эту игру, я изучал ActionScript. В момент, когда я к ней приступил, моё знание этого ЯП было абсолютно нулевым (например, я не понимал, что такое "класс" и "слушатель события"). То есть, все проблемы, с которыми я сталкивался, были для меня неочевидны. Так что и их решения, скорее всего, покажутся сведущим людям капитанскими, как и многое из вышеупомянутого.
В общем, отдельный пост по технической части я не осилю - это проще всего взять код, тщательно закомментировать и выложить. Но если интересуют какие-то конкретные моменты, с удовольствием поделюсь.
Подрывник очень сильно выделяется. Остальные перки не имеют смысла на его фоне.
Особенно учитывая "болезненность" стрелков.
Болезненность, в смысле, неточность? Я им специально погрешность добавил, а то они слишком точно траекторию рассчитывали и всегда стреляли в яблочко.
Подрывник очень силён, да. Ещё мультивыстрел тоже всех уделывает. С балансом в игре всё довольно печально, каюсь
"Болеют" часто, то есть не могут лидерами быть. Нужно всех в подрывника качать для надежности.
Я до 50 ночи с подрывником дошел - никаких проблем. Крестьяне спят, дозор в карты режется от скуки. Все три баррикады целые остаются, до замка вообще никто не доходит. Подрывнику только летуны досаждают иначе бы он один справлялся. Кстати ульи прикрытые тушами "динозавров" другим способом и не поразить, а они сильно бесят лечением противника.
Просто у меня обычно к боссу было максимум 3-4 героя. Я думал, что невелик шанс такой ситуации, когда игрок на первом же герое открывает подрывника, и, оценив его крутость, качает всех остальных тоже в подрывника, несмотря на любопытство "какие ещё есть перки?". Но в целом, да, надо было делать его слабее (за счёт урона, радиуса поражения, расхода энергии или частоты выстрелов), но теперь уже поздно, пусть фигачит) Тем более, взрыв я рисовал долго и старательно, так хоть не зря, выходит)