Выразительный JavaScript (Хавербеке) - страница 165

>    this.pos.y += step;

>    this.size.y -= step;

>  }

>};

После движения метод проверяет других актёров, с которыми игрок сталкивается, и опять вызывает >playerTouched, если таковой нашёлся. В этот раз он передаёт вторым аргументом объект >actor, так как если другим актёром была монетка, метод >playerTouched должен знать, какую именно монетку мы собрали.

В финале, когда игрок погибает (дотронувшись до лавы), мы делаем небольшую анимацию, из-за которой персонаж сжимается (или тонет), уменьшая высоту объекта >player.

Вот метод, обрабатывающий столкновения между игроком и другими объектами:

>Level.prototype.playerTouched = function(type, actor) {

>  if (type == "lava" && this.status == null) {

>    this.status = "lost";

>    this.finishDelay = 1;

>  } else if (type == "coin") {

>    this.actors = this.actors.filter(function(other) {

>      return other != actor;

>    });

>    if (!this.actors.some(function(actor) {

>      return actor.type == "coin";

>    })) {

>      this.status = "won";

>      this.finishDelay = 1;

>    }

>  }

>};

Когда мы тронули лаву, статус игры устанавливается в >“lost”. Когда собрана монетка, она удаляется из массива актёров, а если это была последняя – статус игры меняется на >“won”. Всё это даёт нам уровень, пригодный для анимации. Не хватает только кода, её обрабатывающего.

Отслеживание клавиш

Для такой игры нам не нужны клавиши, эффект которых работает однократно после >keypress. Нам нужен эффект, продолжающийся всё время, пока клавиша нажата (движущаяся фигурка)

Нам надо сделать обработчик клавиш, хранящий текущее состояние кнопок влево, вправо вверх и вниз. Также нам надо вызывать для них >preventDefault, чтобы они не прокручивали страницу.

Следующая функция, когда ей дают объект с кодами клавиш в виде имён свойств и названиями клавиш в виде значений, возвращает другой объект, который отслеживает текущее состояние кнопок. Он регистрирует обработчики событий для событий >"keydown" и >"keyup", и когда код клавиши события совпадает с отслеживаемым кодом, обновляет объект.

>var arrowCodes = {37: "left", 38: "up", 39: "right"};


>function trackKeys(codes) {

>  var pressed = Object.create(null);

>  function handler(event) {

>    if (codes.hasOwnProperty(event.keyCode)) {

>      var down = event.type == "keydown";

>      pressed[codes[event.keyCode]] = down;

>      event.preventDefault();

>    }

>  }

>  addEventListener("keydown", handler);

>  addEventListener("keyup", handler);

>  return pressed;

>}

Обратите внимание, как одна функция обработчика используется для событий обоих типов. Она проверяет свойство >type объекта события, определяя, надо ли обновлять состояние кнопки на