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

>.actor  { position: absolute;            }

>.coin   { background: rgb(241, 229, 89); }

>.player { background: rgb(64, 64, 64);   }

При обновлении экрана метод >drawFrame удаляет старое изображение актёра, если оно было, и затем перерисовывает его на новой позиции. Напрашивается использование элементов DOM в качестве актёров, но для этого нам потребовалось бы передавать слишком много дополнительной информации между кодом дисплея и кодом симуляции. Надо было бы связать актёров с элементами DOM, и код рисования должен был бы удалять элементы при исчезновении актёров. Так как обычно в игре актёров совсем немного, их перерисовка отнимает немного ресурсов.

>DOMDisplay.prototype.drawFrame = function() {

>  if (this.actorLayer)

>    this.wrap.removeChild(this.actorLayer);

>  this.actorLayer = this.wrap.appendChild(this.drawActors());

>  this.wrap.className = "game " + (this.level.status || "");

>  this.scrollPlayerIntoView();

>};

Добавив в обёртку >wrapper текущий статус уровня в виде класса, мы можем стилизовать персонажа по-разному в зависимости от того, выиграна игра или проиграна. Мы добавим правило CSS, которое работает, только когда у игрока есть потомок с заданным классом.

>.lost .player {

>  background: rgb(160, 64, 64);

>}

>.won .player {

>  box-shadow: -4px -7px 8px white, 4px -7px 8px white;

>}

После прикосновения к лаве цвета игрока становятся тёмно-красными, будто он сгорел. Когда последняя монетка собрана, мы используем размытые тени для создания эффекта сияния.

Нельзя предполагать, что уровни всегда вмещаются в окно просмотра. Поэтому нам нужен >scrollPlayerIntoView – он нужен для гарантии того, что если уровень не влезает в окно, он будет прокручен, чтобы игрок всегда был близко к центру. Следующий CSS задаёт обёртке максимальный размер, и гарантирует, что всё вылезающее за него не видно. Также мы задаём элементу позицию >relative, чтобы актёры внутри него располагались относительно его левого верхнего угла.

>.game {

>  overflow: hidden;

>  max-width: 600px;

>  max-height: 450px;

>  position: relative;

>}

В методе >scrollPlayerIntoView мы находим положение игрока и обновляем позицию прокрутки обёртывающего элемента. Мы меняем позицию, работая со свойствами >scrollLeft и >scrollTop, когда игрок подходит близко к краю.

>DOMDisplay.prototype.scrollPlayerIntoView = function() {

>  var width = this.wrap.clientWidth;

>  var height = this.wrap.clientHeight;

>  var margin = width / 3;


>  // The viewport

>  var left = this.wrap.scrollLeft, right = left + width;

>  var top = this.wrap.scrollTop, bottom = top + height;


>  var player = this.level.player;