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

, содержащее позицию (координаты верхнего левого угла), свойство >size с размером, и свойство >type со строчкой, описывающей его тип (>"lava", >"coin" или >"player").

После построения решётки мы используем метод >filter, чтобы найти объект игрока, хранящийся в свойстве уровня. Свойство >status отслеживает, выиграл игрок или проиграл. Когда это случается, используется >finishDelay, которое держит уровень активным некоторое время для показа простой анимации. (Просто сразу восстанавливать состояние уровня или начинать следующий – это выглядит некрасиво). Этот метод можно использовать, чтобы узнать, закончен ли уровень:

>Level.prototype.isFinished = function() {

>  return this.status != null && this.finishDelay < 0;

>};

Действующие лица (актёры)

Для хранения позиции и размера наших актёров мы вернёмся к нашему верному типу >Vector, который группирует координаты x и y в объект.

>function Vector(x, y) {

>  this.x = x; this.y = y;

>}

>Vector.prototype.plus = function(other) {

>  return new Vector(this.x + other.x, this.y + other.y);

>};

>Vector.prototype.times = function(factor) {

>  return new Vector(this.x * factor, this.y * factor);

>};

Метод >times масштабирует вектор, умножая на заданную величину. Это будет удобно, когда нам надо будет умножать вектор скорости на временной интервал, чтобы узнать пройденный путь за это время.

В предыдущей секции конструктором >Level был использован объект >actorChars, чтобы связать символы с функциями конструктора. Объект выглядит так:

>var actorChars = {

>  "@": Player,

>  "o": Coin,

>  "=": Lava, "|": Lava, "v": Lava

>};

Три символа ссылаются на >Lava. Конструктор >Level передаёт исходный символ актёра в качестве второго аргумента конструктора, и конструктор >Lava использует его для корректировки своего поведения (прыгать по горизонтали, прыгать по вертикали, капать).

Тип >player построен следующим конструктором. У него есть свойство >speed, хранящее его текущую скорость, что поможет нам симулировать импульс и гравитацию.

>function Player(pos) {

>  this.pos = pos.plus(new Vector(0, -0.5));

>  this.size = new Vector(0.8, 1.5);

>  this.speed = new Vector(0, 0);

>}

>Player.prototype.type = "player";

Поскольку высотой игрок в полтора квадратика, его начальная позиция задаётся на полквадрата выше позиции, где расположен символ >“@”. Таким образом его низ совпадает с низом квадрата, в котором он появляется.

При создании динамического объекта >Lava, нам надо проинициализировать объект в зависимости от символа. Динамическая лава двигается с заданной скоростью, пока не встретит препятствие. Затем, если у неё есть свойство