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

Часть 30: onTap который не срабатывает при swipe жесте

После решения проблемы с событиями, я приступил к реализации события onTap. Погуглимв немного я нашел, что Phaser его реализовал, но не для объектов, а для сцены: game.input.onTap. Этот недостаток мне удалось очень просто устранить. Достаточно в обработчик события onTap добавить проверку координат нажатия:

var pointer = this.game.input.activePointer;
if (this.getBounds().contains(pointer.positionDown.x, pointer.positionDown.y)) {
}

Такое решение работает, если пользователь прокручивает список более 500 миллисекунд. Но на практике, swipe жест может занимать очень короткое время. Если же в этот момент он находился над кнопкой, то выполнялось оба условия (tap, countains) и срабатывал onTap обработчик.

Вот тут я и решил создать свое правильное onTap событие. Для этого я использовал событие onInputUp, которое срабатывает в момент атжатия пальца над спраитом. В обработчике я рассчитал расстояние, которое палец прошел пока был в нажатом состоянии. Эта дистанция помогает различить touch или swipe жест.

ВАЖНО: свойство positionUp в Phaser обновляется не сразу. При первом отжатии, его значение undefined! Возможно так и задумывалось, но нас это не устраивает. При этом я заметил, что свойства x, y в момент события onInputUp содержат нужные мне координаты. А вот и правильная реализация:

this.inputEnabled = true;
this.events.onInputUp.add(this._on_input_up, this);
this.onTap = new Phaser.Signal();

_on_input_up() {
  var pointer = this.game.input.activePointer;
  var distance = Phaser.Math.distance(pointer.positionDown.x, pointer.positionDown.y, pointer.positionUp.x, pointer.positionUp.y);
  var duration = pointer.timeDown - pointer.timeUp;
  if (distance < 20 && duration < 500) {
    this.onTap.dispatch(this, pointer);
  }
}

Я не зря назвал это событие touch-ом а не tap-ом. Разница в этих событиях в том, что первое срабатывает даже если перед отжатием, палец находился на экране несколько секунд, а второе — очень короткое (500 милисекнуд).

Вот так просто я получил код, который умеет различать tap от swipe. Теперь думаю можно переходить к посту об аудио спраите, тем более мне надо создать их для всех 64 уроков. Спасибо за уделенное время и надеюсь вам был полезен мой пост. Пишите комментарии, задавайте вопросы.

2 thoughts on “Часть 30: onTap который не срабатывает при swipe жесте

  1. Ты реально крут.
    Слежу примерно с 3-5 поста. Очень переживал, что забросишь.
    Завершай поскорее — это приложение реально полезное. А мелкие баги отловишь за счет обратной связи.
    Как минимум один ответственный юзверь, который даст тебе баг репот, у тебя уже есть))

  2. Спасибо большое за поддержку и что следишь за моей работой. Вот именно такие посты дают мне силы продолжать работу над блогом =)

    Я буду очень рад, если ты потестируешь программу. Пример за сегодня, добавил в игру режим экзамена (завтра сможешь посмотреть лично) и сразу появилась техническая проблема. Дело в том, у меня в дизайнер предусмотрено две полоски для прогресса (один кружочек одна карточка, я их еще помечаю красным или зеленым, в зависимости от ответа). Так вот… всего там может поместится 26! Для уроков это нормально, но экзамен подразумевал ответ на ВСЕ вопросы из 4 уроков… но что бы не тормозить процесс работы, для первой версии я решил урезать максимальное количество до 26 (заранее перемешав слова из всех 4 уроков). Но вот варианты ответов я решил все же брать из всех четырех уроков, что бы игрок не смог перейти на другой уровень, не потратив достаточно времени на изучение материала.

    А у самого нет желания написать игру?

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

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