Файл: Беляев С А - Разработка игр на языке JavaScript - 2016.pdf

ВУЗ: Не указан

Категория: Книга

Дисциплина: Программирование

Добавлен: 25.10.2018

Просмотров: 7605

Скачиваний: 136

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

Отображение объектов

61

Условие проверяет, что запрос выполнен корректно.

spriteManager.parseAtlas(request.responseText);

Вызывается функция разбора атласа (parseAtlas) ме

неджера спрайтов результатом запроса. Данная функция
будет рассмотрена ниже. Важно, что функция вызывает
ся не с использованием ключевого слова this, а с исполь
зованием переменной spriteManager.
request.open("GET", atlasJson, true);

Указывается, что запрос будет выполняться с исполь

зованием метода «GET», запрос будет асинхронным и бу
дет выполняться к адресу atlasJson.
request.send();

Отправка запроса:

this.loadImg(atlasImg);

Вызывается функция загрузки изображения (loadImg)

менеджера спрайтов, в качестве параметра — путь к изоб
ражению (atlasImg).
function loadImg(imgName) { // çàãðóçêà èçîáðàæåíèÿ

this.image.onload = function () {

spriteManager.imgLoaded = true; // êîãäà èçîáðàæåíèå

// çàãðóæåíî - óñòàíîâèòü â true

};

this.image.src = imgName; // äàâàéòå çàãðóçèì èçîáðàæåíèå

}

Функция загрузки изображения в качестве параметра

принимает путь к изображению imgName.
this.image.onload = function() { spriteManager.imgLoaded = true; };

В приведенном фрагменте кода полю onload изображе

ния менеджера спрайтов (image) присваивается функция,
содержащая всего одну строку, в которой значение поля
imgLoaded менеджера спрайтов устанавливается в true
(изображение загружено). Данная функция будет вызва
на по окончании загрузки изображения. Важно, что внут
ри функции для обращения к полю imgLoaded использу
ется не ключевое слово this, а переменная spriteManager.
this.image.src = imgName;


background image

62

Глава 3

Полю src объекта image присваивается путь imgName,

после чего JavaScript начинает загрузку изображения.

function parseAtlas(atlasJSON) { // ðàçîáðàòü àòëàñ ñ îáúåêòàìè

var atlas = JSON.parse(atlasJSON);

for (var name in atlas.frames) { // ïðîõîä ïî âñåì èìåíàì â frames

var frame = atlas.frames[name].frame; // ïîëó÷åíèå ñïðàéòà è

// ñîõðàíåíèå â frame

// ñîõðàíåíèå õàðàêòåðèñòèê frame â âèäå îáúåêòà

this.sprites.push({name: name, x: frame.x, y: frame.y, w: frame.w, h:

frame.h});

}

this.jsonLoaded = true; // êîãäà ðàçîáðàëè âåñü àòëàñ - true

}

Функция parseAtlas в качестве параметра принимает

атлас в формате JSON (atlasJSON). По сравнению с разбо
ром JSON карты из 2 главы предлагаемый метод намного
проще и короче.

var atlas = JSON.parse(atlasJSON);

Функция parse встроенного объекта JSON принимает

в качестве параметра JSON в виде строки, а возвращает
объект, который сохраняется в новую переменную atlas.

for (var name in atlas.frames)

Цикл по всем именам спрайтов в атласе:

var frame = atlas.frames[name].frame;

Создание новой переменной frame, в которой сохраня

ется объектспрайт из загруженного атласа.

this.sprites.push({name:  name,  x:  frame.x,  y:  frame.y,  w:  frame.w,  h:

frame.h});

У массива спрайтов sprites вызывается метод добав

ления объекта в качестве последнего элемента массива
(push). При этом создается новый объект, содержащий
пять параметров: имя (name), координаты (xy) и разме
ры (w,  h). В рассматриваемом примере вся необходимая
информация хранится в спрайте (frame), если размеры в
переменной frame не совпадают с реальными размерами


background image

Отображение объектов

63

спрайта или спрайт был повернут, то разработчику необ
ходимо получить из atlas.frames[name] необходимые ему
объекты и поля и соответствующим образом обработать.

this.jsonLoaded = true;

По окончании цикла в переменной jsonLoaded сохра

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

function drawSprite(ctx, name, x, y) {

// åñëè èçîáðàæåíèå íå çàãðóæåíî, òî ïîâòîðèòü çàïðîñ ÷åðåç

// 100 ìñåê

if (!this.imgLoaded || !this.jsonLoaded) {

setTimeout(function () { spriteManager.drawSprite(ctx, name,

x, y); }, 100);

} else {

var sprite = this.getSprite(name); // ïîëó÷èòü ñïðàéò ïî èìåíè

if(!mapManager.isVisible(x, y, sprite.w, sprite.h))

return; // íå ðèñóåì çà ïðåäåëàìè âèäèìîé çîíû

// ñäâèãàåì âèäèìóþ çîíó

x -= mapManager.view.x;

y -= mapManager.view.y;

// îòîáðàæàåì ñïðàéò íà õîëñòå

ctx.drawImage(this.image, sprite.x, sprite.y, sprite.w, sprite.h, x,

y, sprite.w, sprite.h);

}

}

Функция отображения спрайтов (drawSprite) прини

мает в качестве параметров контекст холста (ctx), имя
спрайта, требующего отображения (name), координаты, в
которых необходимо отобразить спрайт (xy).

if (!this.imgLoaded || !this.jsonLoaded)

Выполняется проверка, что изображение и атлас за

гружены, иначе используется таймер для повторного вы
зова функции отображения спрайтов.

setTimeout(function  ()  {  spriteManager.drawSprite(ctx,  name,  x,  y);  },

100);


background image

64

Глава 3

Встроенная функция setTimeout в качестве парамет

ра принимает функцию, которую необходимо вызвать по
таймеру и время в миллисекундах (в данном примере —
100 мс). В качестве функции вызывается drawSprite с теми
же параметрами.

var sprite = this.getSprite(name);

С использованием функции getSprite, которая прини

мает в качестве параметра имя спрайта (name) и будет опи
сана ниже, в новую переменную (sprite) сохраняется спрайт.

if(!mapManager.isVisible(x, y, sprite.w, sprite.h))

Используется предусмотрительно подготовленная функ

ция isVisible менеджера карты, которая сообщает: виден
ли спрайт на экране, если нет, то выполняется выход из
функции отображения спрайта (return).

x -= mapManager.view.x; y -= mapManager.view.y;

Координаты спрайта (x,  y) передаются относительно

карты, а не относительно видимой части карты, поэтому
используется объект view менеджера карты (mapManager)
для сдвига координат.

ctx.drawImage(this.image, sprite.x, sprite.y, sprite.w, sprite.h, x, y, sprite.w,

sprite.h);

Функция  drawImage контекста холста отображает

фрагмент изображения (image), описанный координата
ми (sprite.xsprite.y) и размерами (sprite.wsprite.h) в за
данных координатах (xy) с теми же размерами (sprite.x,
sprite.y).

Для работы функции drawSprite необходима функция

getSprite, обеспечивающая получение спрайта по имени.
function getSprite(name) { // ïîëó÷èòü îáúåêò ïî èìåíè

for (var i = 0; i < this.sprites.length; i++) {

var s = this.sprites[i];

if (s.name === name) // èìÿ ñîâïàëî - âåðíóòü îáúåêò

return s;

}

return null; // íå íàøëè

}


background image

Отображение объектов

65

Функция получения спрайта (getSprite) в качестве

параметра использует его имя (name).
for (var i = 0; i < this.sprites.length; i++)

Организуется цикл for по всем элементам массива

sprites (от 0 до sprites.length) с использованием времен
ной переменной i.
var s = this.sprites[i];

Создается временная переменная s, в которую сохра

няется элемент массива (sprites) с номером i.
if (s.name === name)

Проверяется, что имя элемента массива совпадает с

искомым.
return s;

Возвращает найденный спрайт.

return null;

Если цикл for закончился, значит, спрайт с заданным

именем (name) не найден, поэтому возвращается значе
ние null.

Подготовленный менеджер спрайтов позволяет допол

нить созданные объекты из параграфа 3.1. Например, функ
ция draw объектов Player и Tank может выглядеть следую
щим образом:
function draw(ctx) { // ïðîðèñîâêà îáúåêòà

spriteManager.drawSprite(ctx, "tank_left_1", this.pos_x, this.pos_y);

}

Идентично может выглядеть отображение объекта

Bonus.
function draw(ctx) { // ïðîðèñîâêà îáúåêòà

spriteManager.drawSprite(ctx, "star", this.pos_x, this.pos_y);

}

Для Rocket:

function draw(ctx) { // ïðîðèñîâêà îáúåêòà

spriteManager.drawSprite(ctx, "rocket_up", this.pos_x, this.pos_y);

}