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

, который будет поддерживать тот же интерфейс, что и >DOMDisplay из главы 15, а именно, методы >drawFrame и >clear.

Объект хранит больше информации, чем >DOMDisplay. Вместо использования позиции прокрутки элемента DOM, он отслеживает окно просмотра, которое сообщает, какую часть уровня мы сейчас видим. Также он отслеживает время и использует это, чтобы решить, какой кадр анимации показывать. И ещё он хранит свойство >flipPlayer, чтобы даже когда игрок стоял на месте, он был повёрнут в ту сторону, в которую шёл в последний раз.

>function CanvasDisplay(parent, level) {

>  this.canvas = document.createElement("canvas");

>  this.canvas.width = Math.min(600, level.width * scale);

>  this.canvas.height = Math.min(450, level.height * scale);

>  parent.appendChild(this.canvas);

>  this.cx = this.canvas.getContext("2d");


>  this.level = level;

>  this.animationTime = 0;

>  this.flipPlayer = false;


>  this.viewport = {

>    left: 0,

>    top: 0,

>    width: this.canvas.width / scale,

>    height: this.canvas.height / scale

>  };


>  this.drawFrame(0);

>}


>CanvasDisplay.prototype.clear = function() {

>  this.canvas.parentNode.removeChild(this.canvas);

>};

В 15 главе мы передавали размер шага в >drawFrame из-за счётчика >animationTime, несмотря на то, что >DOMDisplay его не использовал. Наша новая функция >drawFrame использует его для отсчёта времени, чтобы переключаться между кадрами анимации в зависимости от текущего времени.

>CanvasDisplay.prototype.drawFrame = function(step) {

>  this.animationTime += step;


>  this.updateViewport();

>  this.clearDisplay();

>  this.drawBackground();

>  this.drawActors();

>};

Кроме отслеживания времени, метод обновляет окно просмотра текущей позиции игрока, заполняет холст цветом фона, и рисует фон и актёров. Заметьте, что всё происходит не так, как в главе 15, где мы рисовали фон один раз, а затем прокручивали оборачивающий элемент DOM для перемещения по нему.

Так как формы на холсте – всего лишь пиксели, после их отрисовки их нельзя сдвинуть (или убрать). Единственным способом обновить холст будет очистить его и перерисовать сцену.

Метод >updateViewport похож на метод >scrollPlayerIntoView из >DOMDisplay. Он проверяет, не находится ли игрок слишком близко к краю экрана и двигает окно просмотра, если это случается.

>CanvasDisplay.prototype.updateViewport = function() {

>  var view = this.viewport, margin = view.width / 3;

>  var player = this.level.player;

>  var center = player.pos.plus(player.size.times(0.5));


>  if (center.x < view.left + margin)

>    view.left = Math.max(center.x - margin, 0);

>  else if (center.x > view.left + view.width - margin)