HTML5 Phaser ECMAScript 6, Phaser - полезные советы

Часть 33: Как быстро создавать элементы интерфейса в игре

Добавил в игру два новых окошка для экзамена: победа и поражение. Обратите внимание на заголовок окошка поражения. Я заведомо написал «победа близка», что бы ободрить игрока. Это очень важно делать!

окошко поражения экзамена с анимированным прогрессом

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

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

окошко сдачи экзамена

Неожиданно много времени ушло на рефакторинг и перевод первых сцен на новый стандарт. В результате код стал значительно чище, а в папке для графики всего несколько изображений и файлов JSON формата. Мне это очень нравиться! Я уже больше месяца работаю над этой обучающей игрой и хочу поделиться моими наблюдениями:

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

Одно дело хотеть, а другое дело сделать. За все это время у меня было несколько попыток: сначала делал на основе Phaser.Group, позже на базе Phaser.Sprite (читайте посты тут и тут). Но направление было ошибочным… главное не на чем основан элемент интерфейса, а какие у него есть свойства. Рассмотрим мою игру для примера. Не смотря на разнообразие элементов интерфейса, все они имеют иконку и текст. Иконка или текст всегда выравнены по центру либо по горизонтальной оси, либо — вертикальной.

пример элементов сделанных на базе Panel с свойствами icon и label

По этому я создал для себя базовый класс Panel (кнопка назад в примере ниже) у которого есть свойства icon, label и метод update_skin, который вызывается при любых изменениях связанных с интерфейсом. Я также добавил два свойства icon_offset и label_offset, через которые я задаю отступы слева, сверху, справа и снизу для этих элементов. В результате, если мне надо создать вот такой вот счетчик:

пример реализации нового элемента на базе Panel прямоугольником выделены секции для позиционирования иконки и текста

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

_update_skin() {
  super._update_skin();

  this.icon_offset = {right: this.width - this.height};
  this.label_offset = {left: this.height, right: 10};
}

После этого я добавил два важных свойства can_pulse, can_shake. Первое включает пульсацию при нажатии (идеально для кнопок), второе делает горизонтальное пошатывание (знак нет) если элемент заблокирован (locked = true).

Из событий я реализовал сразу два Phaser.Signal: onTap и onTapComplete. На практике нужно иметь оба варианта. Первый срабатывает сразу при нажатии, второй только после того, как анимация нажатия завершена (пульсация или пошатывание). Если пользователь нажимает на кнопку назад, то надо сначала показать анимацию, а потом переключить на новую сцену… но если пользователь нажал на стрелку прокрутки, то скролинг должен сработать без задержки (параллельно с анимацией нажатия на кнопку).

В следующем посте я вам расскажу про очередной глюк Phaser и как его решить. Не стесняемся и пишем комментарии, вопросы или пожелания =) Заранее спасибо!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *