Файл: Беляев С А - Разработка игр на языке JavaScript - 2016.pdf
Добавлен: 25.10.2018
Просмотров: 7603
Скачиваний: 136
56
Глава 3
в виду, что данная реализация имеет важное ограниче
ние: выстрел будет выполняться, только если move_x или
move_y не равны нулю, т. е. игрок движется.
gameManager.entities.push(r);
Сохраняет созданный объект r в массив объектов
(entities) менеджера игры (gameManager).
Идентично можно создать метод fire для объекта Tank.
Если разработчик игры предполагает большее коли
чество объектов, их следует описать аналогичным спосо
бом. Реализация функции draw будет рассмотрена ниже.
3.2.
ЗАГРУЗКА ИЗОБРАЖЕНИЙ ДЛЯ ОБЪЕКТОВ
Размещение множества изображений в одном файле
позволяет существенно уменьшить время их загрузки в
браузер. При этом одновременно с файлом изображения
необходимо сформировать описание, в котором будет хра
ниться информация о размещении каждого отдельного
изображения. Общее описание при этом принято называть
«атлас», а каждое отдельное изображение — «спрайт».
Атласы могут быть представлены в самых разных форма
тах — это текст, CSS, XML, JSON и т. д. В рамках данного
пособия остановимся только на формате JSON.
Существует множество программ, позволяющих объе
динять изображения и формировать атласы. Например,
условнобесплатная программа, предоставляющая боль
шое количество возможностей по формированию атла
сов и поддерживающая много форматов сохранения —
TexturePacker [10]. Для сохранения в формате JSON мож
но ограничиться бесплатной программой Leshy SpriteSheet
Tool [11]. Внешний вид редактора приведен на рисунке 3.1.
Редактор Leshy SpriteSheet Tool в качестве источни
ка информации использует изображения спрайтов. Спрай
ты могут быть разных размеров и форм, они размещаются
в одном изображении таким образом, чтобы занимать как
можно меньше места. Задача размещения является NP
трудной, поэтому редакторы ищут не точное, приближен
Отображение объектов
57
ное решение и всегда есть несколько способов размеще
ния. В приведенном примере спрайты имеют одинаковые
размеры и дубликаты для четырех направлений (вверх,
вниз, влево и вправо). В общем случае достаточно иметь
одно направление и осуществлять программный поворот
спрайтов (см. п. 1.6), при этом допустимо использовать
спрайты разных размеров.
Рассмотрим, в каком формате сохраняются атласы на
примере atlas.json, приведенного на рисунке 3.1 (много
точием заменены фрагменты JSON). Важно обратить вни
мание, что форматов хранения JSON множество, в вари
анте Leshy SpriteSheet Tool данный формат хранения на
зывается «JSONTPHASH».
Рис. 3.1
Внешний вид редактора Leshy SpriteSheet Tool
58
Глава 3
{ "frames":{
"rocket_down":{
"frame":{ "x":0, "y":65, "w":64, "h":64 },
"rotated":false,
"trimmed":false,
"spriteSourceSize":{ "x":0, "y":0, "w":64, "h":64 },
"sourceSize":{ "w":64, "h":64 }
},
"rocket_left":{
"frame":{ "x":130, "y":130, "w":64, "h":64 },
"rotated":false,
"trimmed":false,
"spriteSourceSize":{ "x":0, "y":0, "w":64, "h":64 },
"sourceSize":{ "w":64, "h":64 }
},
},
"meta":{
"app":"http://www.leshylabs.com/apps/sstool/",
"version":"Leshy SpriteSheet Tool v0.8.1",
"size":{ "w":320, "h":384 },
"scale":1
}
}
Поле frames содержит в себе множество объектов, опи
сывающих спрайты, обращение к которым осуществляет
ся по имени. Примеры имен: rocket_down, rocket_left.
Разработчик может заранее не знать перечень полей объек
та, для перебора полей можно воспользоваться циклом for,
например, таким способом: for(var key in frames), где
frames — имя объекта, а key будет последовательно при
нимать значения всех имен полей из frames. Обратиться к
отдельному объекту по имени в приведенном примере мож
но следующим образом: frames[key].
Каждый спрайт содержит стандартный набор полей:
описание координат и размеров спрайта в изображении
(frame), признак того, что спрайт хранится в повернутом
виде (rotated), признак того, что спрайт хранится в «обре
занном» виде (trimmed), исходный размер спрайта до «обре
зания» (spriteSourceSize), размеры спрайта (sourceSprite).
Отображение объектов
59
Объекты frame и spriteSourceSize имеют одинаковую
структуру: координаты (x, y), ширина (w) и высота (h).
Объект sourceSize хранит информацию о ширине (w) и
высоте (h).
В рассматриваемом примере все спрайты квадратные,
их поворот никак не изменит варианты размещения, по
этому признак rotated в приведенном коде принимает зна
чение false (без поворота). В общем случае поворот может
осуществляться на 90
°.
В рассматриваемом примере в программе не использо
вана оптимизация для удаления прозрачных областей по
краям, поэтому признак trimmed в приведенном коде при
нимает значение false (без «обрезания»). В случае удале
ния прозрачных областей по краям перестанут совпадать
параметры спрайта в frame и spriteSourceSize. При этом
центр спрайта в исходном коде может не совпасть с цент
ром спрайта в полученном изображении (с какойто сто
роны могло быть удалено больше прозрачной области),
тогда разработчику необходимо будет учитывать измене
ние центра объекта при его отображении пользователю и
обработке логики в игре.
Метаинформация (meta) хранит дополнительную ин
формацию, в том числе размер изображения (size) в виде
ширины (w) и высоты (h).
В данном учебном пособии объект для управления
спрайтами (или менеджера спрайтов) будет называться
spriteManager. Рассмотрим структуру менеджера спрайтов:
var spriteManager = {
image: new Image(), // ðèñóíîê ñ îáúåêòàìè
sprites: new Array(), // ìàññèâ îáúåêòîâ äëÿ îòîáðàæåíèÿ
imgLoaded: false, // èçîáðàæåíèÿ çàãðóæåíû
jsonLoaded: false // JSON çàãðóæåí
}
Аналогичный подход и методы по созданию менедже
ра управления спрайтами представлены в [9], [10]. В при
веденном коде показаны только поля, функции будут опи
саны отдельно.
image: new Image()
60
Глава 3
Поле для хранения изображения (image) инициализи
руется как изображение с использованием встроенного
объекта Image.
sprites: new Array()
Поле для хранения объектов спрайтов (sprites) ини
циализируется как массив с использованием встроенного
объекта Array.
Поля imgLoaded и jsonLoaded предназначены для хра
нения признаков загрузки изображения и атласа (JSON
описания информации о хранении спрайтов в изобра
жении).
Загрузка атласа изображения осуществляется с ис
пользованием функции loadAtlas:
function loadAtlas(atlasJson, atlasImg) {
var request = new XMLHttpRequest(); // ïîäãîòîâèòü çàïðîñ íà
// ðàçáîð àòëàñà
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
spriteManager.parseAtlas(request.responseText); // óñïåøíî
// ïîëó÷èëè àòëàñ
}
};
request.open("GET", atlasJson, true); // àñèíõðîííûé çàïðîñ íà
ðàçáîð àòëàñà
request.send(); // îòïðàâèëè çàïðîñ
this.loadImg(atlasImg); // çàãðóçêà èçîáðàæåíèÿ
}
Функция loadAtlas имеет два параметра: путь к фай
лу атласа в формате JSON (atlasJson) и путь к изображе
нию (atlasImg). Загрузка осуществляется с использовани
ем уже описанной в данном пособии ajaxтехнологии.
var request = new XMLHttpRequest();
Создается переменная запроса (request) на основании
встроенного объекта XMLHttpRequest. Полю onreadysta
techange запроса присваивается функция, которая будет
вызвана по результатам выполнения запроса.
if (request.readyState === 4 && request.status === 200)