Марейн Хавербеке - Выразительный JavaScript

Тут можно читать онлайн Марейн Хавербеке - Выразительный JavaScript - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.

Марейн Хавербеке - Выразительный JavaScript краткое содержание

Выразительный JavaScript - описание и краткое содержание, автор Марейн Хавербеке, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

В процессе чтения вы познакомитесь с основами программирования и, в частности, языка JavaScript, а также выполните несколько небольших проектов. Один из самых интересных проектов — создание своего языка программирования.

Выразительный JavaScript - читать онлайн бесплатно полную версию (весь текст целиком)

Выразительный JavaScript - читать книгу онлайн бесплатно, автор Марейн Хавербеке
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

function DOMDisplay(parent, level) {

this.wrap = parent.appendChild(elt("div", "game"));

this.level = level;

this.wrap.appendChild(this.drawBackground());

this.actorLayer = null;

this.drawFrame();

}

Используя тот факт, что appendChildвозвращает добавленный элемент, мы создаём окружающий элемент wrapperи сохраняем его в свойстве wrap.

Неизменный фон уровня рисуется единожды. Актёры перерисовываются каждый раз при обновлении экрана. Свойство actorLayerиспользуется в drawFrameдля отслеживания элемента, содержащего актёра – чтобы их было легко удалять и заменять.

Координаты и размеры измеряются в единицах, относительных к размеру решётки так, что дистанция в единицу означает один элемент решётки. Когда мы задаём размеры в пикселях, нам нужно будет масштабировать координаты – игра была бы очень мелкой, если б один квадратик задавался одним пикселем. Переменная scaleдаёт количество пикселей, которое занимает один элемент решётки.

var scale = 20;

DOMDisplay.prototype.drawBackground = function() {

var table = elt("table", "background");

table.style.width = this.level.width * scale + "px";

this.level.grid.forEach(function(row) {

var rowElt = table.appendChild(elt("tr"));

rowElt.style.height = scale + "px";

row.forEach(function(type) {

rowElt.appendChild(elt("td", type));

});

});

return table;

};

Как мы уже упоминали, фон рисуется через элемент

. Это удобно соответствует тому факту, что уровень задан в виде решётки – каждый ряд решётки превращается в ряд таблицы (элемент ). Строки решётки используются как имена классов ячеек таблицы (
). Следующий CSS приводит фон к необходимому нам внешнему виду:

.background { background: rgb(52, 166, 251);

table-layout: fixed;

border-spacing: 0; }

.background td { padding: 0; }

.lava { background: rgb(255, 100, 100); }

.wall { background: white; }

Некоторые из настроек ( table-layout, border-spacingи padding) используются для подавления нежелательного поведения по умолчанию. Не нужно, чтобы вид таблицы зависел от содержимого ячеек, и не нужны пробелы между ячейками или отступы внутри них.

Правило backgroundзадаёт цвет фона. CSS разрешает задавать цвета словами ( white) и в формате rgb(R, G, B), где красная, зелёная и синяя компоненты разделены на три числа от 0 до 255. То есть, в записи rgb(52, 166, 251)красный компонент равен 52, зелёный 166 и синий 251. Поскольку синий компонент самый большой, результирующий цвет будет синеватым. Вы можете видеть, что самый большой компонент в правиле .lava– красный.

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

DOMDisplay.prototype.drawActors = function() {

var wrap = elt("div");

this.level.actors.forEach(function(actor) {

var rect = wrap.appendChild(elt("div",

"actor " + actor.type));

rect.style.width = actor.size.x * scale + "px";

rect.style.height = actor.size.y * scale + "px";

rect.style.left = actor.pos.x * scale + "px";

rect.style.top = actor.pos.y * scale + "px";

});

return wrap;

};

Чтобы задать элементу больше одного класса, мы разделяем их имена пробелами. В коде CSS класс actorзадаёт позицию absolute. Имя типа используется в дополнительном классе для задания цвета. Нам не надо заново определять класс lava, потому что мы повторно используем класс для лавы из решётки, который мы определили ранее.

.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;

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

.times(scale);

if (center.x < left + margin)

this.wrap.scrollLeft = center.x - margin;

else if (center.x > right - margin)

this.wrap.scrollLeft = center.x + margin - width;

if (center.y < top + margin)

this.wrap.scrollTop = center.y - margin;

else if (center.y > bottom - margin)

this.wrap.scrollTop = center.y + margin - height;

};

Метод нахождения центра игрока показывает, как методы наших типов Vectorпозволяют записывать расчёты, производимые с объектами, наглядно. Чтобы найти центр актёра, мы добавляем его позицию (его левый верхний угол) и половину высоты. Это центр в координатах уровня, но нам он нужен в координатах пикселей, поэтому мы умножаем результирующий вектор на наш масштаб.

Затем серия проверок подтверждает, что игрок не находится вне доступного пространства. Иногда в результате будут заданы неправильные координаты прокрутки, ниже нуля или больше, чем размер прокручиваемого элемента. Но это не страшно – DOM автоматически ограничит их допустимыми значениями. Если назначить scrollLeftзначение -10, он будет равен 0.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Марейн Хавербеке читать все книги автора по порядку

Марейн Хавербеке - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Выразительный JavaScript отзывы


Отзывы читателей о книге Выразительный JavaScript, автор: Марейн Хавербеке. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x