HTML5 Phaser ECMAScript 6

Часть 17: Реализация swipe жеста и равномерная прокрутка

Сегодня я хочу вам рассказать о том, как решил задачу плавной прокрутки swipe жестом. Перед тем как начинать решать задачу, надо что бы на сцене было достаточно контента, а это, 80 кнопок уроков. Конечно их можно было расположить программно (процедурная генерация интерфейса), но мне надо было привыкать к Tiled редактору сцен.

Вся работа заняла не более нескольких минут: gоправив координаты всех пяти кнопок, я банально продублировал их 15 раз. Но пришлось заранее отредактировать в текстовом редакторе xml файл карты, что бы увеличить количество ячеек по высоте, так как в Tiled это свойство карты почему то read only. В результате карта вышла довольно высокой, чуть больше 8000 точек. Но вы можете не волноваться, Phaser не обновляет объекты, которые находятся за пределами сцены, соответственно на них не тратиться процессорное время.

вот как выглядит сцена в Tiled редакторе, пришлось уменьшить размер, что бы она уместилась =)

В самом коде не пришлось ничего менять. Достаточно было экспортировать новую карту из Tiled редактора и обновив страницу в браузере.

новые кнопки уроков автоматически создались за пределами сцены

Конечно, надо было подумать о реализации overflow:hidden в Phaser, но я решил начать все же с прокрутки. В первую очередь я попробовал это сделать через объект camera. У него есть возможность автоматически следовать за объектом (как в платформерах), но тут не было главного героя. Но были свойства camera.x и camera.y для ее ручного перемещения.

Недостатком такого подхода стало то, что вместе с меню, перемещались и остальные элементы интерфейса =) Исправить это недоразумение оказалось очень просто, задав объекту или группе fixedToCamera. Но тут я подумал, а почему бы не перемещать группу (в которую я ранее добавил все кнопки), вместо камеры? Проверил и все работает!

this.game.add.tween(this.lesson).to({y: this.lesson.y + 512}, 750, Phaser.Easing.Quartic.Out, true);

Теперь у меня была прокрутка по нажатию на стрелочки. Для первой версии игры более чем достаточно. Но у меня еще оставалось немного свободного времени (спасибо Tiled), и я решил попробовать реализовать swipe жест. В Phaser не реализованы даже базовые жесты, для них официальный сайт советует использовать плагин Phaser-Swipe.

Попробовав его на практике, я понял что это лучше чем просто кнопки, но не интуитивно. Вы обращали внимание на прокрутку на мобильном? После того как вы отпускаете палец, прокрутка продолжается еще некоторое время, как бы по инерции. При слове инерция, сразу начинаешь думать о физике. Phaser дает возможность задавать velocity (ускорение) физическим объектам, но времени разбирать новый материал не было.

Вот как я упростил задачу: для начала я сообщил Phaser, что меня интересует только один палец this.game.input.maxPointers = 1 (исключил мультитач); а для работы с этим одним пальцем я использовал this.game.input.activePointer (кстати, Phaser сам заменит палец на указатель мышки, если игру запустить на ПК).

Остальное довольно тривиально, в методе update() ловим момент нажатия пальца и высчитываем дельту «input.activePointer.position.y — activePointer.positionDown.y«. Дельта дает нам направление и расстояние. Но что бы реализовать прокрутку, мы должны сохранить исходные координаты нашего списка и добавлять дельту именно к этому значению:

if (this.game.input.activePointer.isDown) {
  if (this.swipe === null) this.swipe = {start: {y: this.lesson.y}, delta_y: 0};
  this.swipe.delta_y = this.game.input.activePointer.position.y - this.game.input.activePointer.positionDown.y;
  if (this.swipe.delta_y < 0) {
    this.lesson.y = this.swipe.start.y - Math.abs(this.swipe.delta_y);
  } else {
    this.lesson.y = this.swipe.start.y + Math.abs(this.swipe.delta_y);
  }
}

ПРАВКА: Равномерную прокрутку можно сделать еще проще. Дело в том, что у Phaser есть возможность включать автоматическое перетаскивание методом свойством enableDrag, а вот через boundsSprite можно задать границы. А если эти границы по ширине равны ширине самого списка, то перетаскивание будет работать только вверх и вниз =)

Вот так я получил равномерную прокрутку. Но как на счет ускорения, о котором я говорил выше? Читайте продолжение в следующем посте.

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

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