, который будет поддерживать тот же интерфейс, что и >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)