Файл: Беляев С А - Разработка игр на языке JavaScript - 2016.pdf
Добавлен: 25.10.2018
Просмотров: 7591
Скачиваний: 136
26
Глава 2
"orientation": "orthogonal",
"properties": {},
"tileheight": 64,
"tilesets": [
{"firstgid": 1,
"image": "img\/tankattack.png",
"imageheight": 384,
"imagewidth": 320,
"margin": 0,
"name": "tankattack",
"properties": {},
"spacing": 0,
"tileheight": 64,
"tilewidth": 64
},
{"firstgid": 31,
"image": "img\/filled.png",
"imageheight": 64,
"imagewidth": 64,
"margin": 0,
"name": "filled",
"properties":{},
"spacing": 0,
"tileheight": 64,
"tilewidth": 64
}],
"tilewidth": 64,
"version": 1,
"width": 30
}
Основные свойства height и width описывают количе
ство блоков по горизонтали и по вертикали, из которых
состоит карта, соответственно tileheight и tilewidth пока
зывают размеры одного блока. Массив layers содержит
объекты для каждого слоя, массив tilesets — объекты,
описывающие каждый рисунок, из которого строится кар
та игры.
Каждый объект tilesets содержит описание для набо
ра блоков, из которых строится карта. Ключевые свой
ства:
Отображение карты игры
27
· tileheight и tilewidth хранят высоту и ширину блока,
на которые разбивается изображение;
· image — путь до изображения;
· firstgid — номер первого блока, используемого из дан
ного изображения;
· name — отображаемое в редакторе имя набора блоков.
Следует обратить внимание, что firstgid формируется
с учетом всех изображений, использованных в карте. Чем
больше блоков поместилось на предыдущем рисунке, тем
больше номер firstgid в следующем наборе блоков. Счита
ется, что нумерация блоков в рамках одного изображения
слева направо и сверху вниз, но нигде явно эта информа
ция не сохраняется. Соответственно, номер следующего
firstgid на единицу больше, чем номер максимального бло
ка в предыдущем рисунке.
Массив layers хранит объекты двух типов (поле type):
tilelayer и objectgroup. Объекты типа tilelayer описывают
слой блоков карты, а объекты типа objectgroup описыва
ют объекты, размещенные на карте.
Поля height и width объекта типа tilelayer содержат
количество блоков, помещающихся, соответственно, по
высоте и по ширине в данном слое, name — его имя, и са
мое главное поле — массив data, который содержит номе
ра всех блоков, отображаемых на карте. Несмотря на то
что массив одномерный, он хранит информацию обо всей
карте: известно количество блоков по горизонтали, соот
ветственно, первые width блоков относятся к первой стро
ке блоков на карте, вторые — ко второй и т. д. По номеру
блока можно восстановить его координаты и в каком изоб
ражении (tilesets) он находится.
Объект типа objectgroup в поле objects хранит массив
объектов, отображаемых на карте. Каждый объект имеет
имя (name), тип (type) и координаты (x, y). Имя и тип впи
сываются дизайнером карты в виде текста, следователь
но, они должны отвечать требованиям обработчиков, опи
санным в тексте программы. Для каждого типа должны
быть созданы соответствующие объекты (глава 3), их име
на должны быть уникальны. Целесообразно ввести под
ходящее имя для объекта, обозначающего игрока, чтобы
28
Глава 2
у дизайнера карты была возможность разместить игрока
в произвольном месте. В приведенном примере введены
три типа: Bonus, Tank и Player. Игрок назван «player».
На первый взгляд, получается достаточно сложное опи
сание JSON, но если учесть, что бóльшая часть данных в
JSON формируется в визуальном редакторе и данное реше
ние позволяет отделить дизайнера от разработчика логи
ки игры, то преимущество становится очевидным. В рам
ках настоящей главы будет выполняться автоматический
разбор информации, хранящейся в слое tilelayer.
2.2.
ОПИСАНИЕ ОБЪЕКТА
ДЛЯ УПРАВЛЕНИЯ КАРТОЙ
В данном учебном пособии объект для управления кар
той (или менеджера карты) будет называться mapManager.
Существует множество способов создать такой объект в
JavaScript, например:
var mapManager = {}; //  ôèãóðíûõ ñêîáêàõ ïåðå÷èñëèòü ïîëÿ è
// ìåòîäû
Или:
var mapManager = new Object();
// Çàòåì äîáàâèòü íåîáõîäèìûå ïîëÿ è ìåòîäû
Или:
var mapManager = Object.create({});
//  ôèãóðíûõ ñêîáêàõ ïåðå÷èñëèòü ïîëÿ è ìåòîäû
Рассмотрим, какие поля являются необходимыми для
менеджера карты.
var mapManager = {
mapData: null, // ïåðåìåííàÿ äëÿ õðàíåíèÿ êàðòû
tLayer: null, // ïåðåìåííàÿ äëÿ õðàíåíèÿ ññûëêè íà áëîêè êàðòû
xCount: 0, // êîëè÷åñòâî áëîêîâ ïî ãîðèçîíòàëè
yCount: 0, // êîëè÷åñòâî áëîêîâ ïî âåðòèêàëè
tSize: {x: 64, y: 64}, // ðàçìåð áëîêà
mapSize: {x: 64, y: 64}, // ðàçìåð êàðòû â ïèêñåëàõ (âû÷èñëÿåòñÿ)
tilesets: new Array() // ìàññèâ îïèñàíèé áëîêîâ êàðòû
}
Отображение карты игры
29
Все исходные данные карты представляют собой объ
ект JSON, который полезно хранить внутри менеджера
карты, для этого в нем создадим поле mapData. Его на
чальное значение — пусто, после инициализации — весь
объект, описанный в параграфе 2.1. Аналогичный подход
и методы по созданию менеджера карты представлены в
[9], [10].
Для удобства доступа к слою карты рекомендуется от
дельно хранить поле tLayer, в котором разместить весь
JSON с типом tilelayer. В рамках данной книги предпола
гается, что такой слой один, при необходимости создания
нескольких слоев разработчику придется сохранять мас
сив таких объектов.
Для корректной работы с картой необходимо знать ее
ширину и высоту в блоках — это поля xCount и yCount,
размер блока — объект tSize, содержащий размеры по
ширине и высоте (x, y). Полезным будет размер карты
mapSize, который содержит размеры по ширине и высоте
(x, y) и легко вычисляется по размеру блока и их количе
ству по ширине и высоте, но позволяет сэкономить время
во время вычислений, так как размер карты будет исполь
зоваться на каждом цикле ее обновления.
Массив tilesets в данном случае создан с использова
нием ключевого слова new и встроенного объекта Array.
В этом массиве будут храниться описания для каждого
блока карты: их номера, размеры, координаты и т. д.
Загрузка карты в формате JSON из внешнего файла бу
дет выполняться с использованием так называемой AJAX
технологии (от англ. Asynchronous Javascript and XML).
Эта технология позволяет отправлять запросы на сервер и
получать их асинхронно, т. е. не останавливая процесс
выполнения JavaScript в браузере. Главное преимущество
AJAX — возможность обновления части HTMLстраницы
без перезагрузки страницы целиком.
function loadMap(path) {
var request = new XMLHttpRequest(); // ñîçäàíèå ajax-çàïðîñà
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
30
Глава 2
// Ïîëó÷åí êîððåêòíûé îòâåò, ðåçóëüòàò ìîæíî
îáðàáàòûâàòü mapManager.parseMap(request.responseText);
}
};
request.open("GET", path, true);
// true - îòïðàâèòü àñèíõðîííûé çàïðîñ íà path
// c èñïîëüçîâàíèåì ôóíêöèè GET
request.send(); // îòïðàâèòü çàïðîñ
}
Функция loadMap принимает в качестве параметра
путь (path) к файлу, который необходимо загрузить. Это
может быть как относительный (например, «tiledmap.
json», если JSON с картой расположен в той же папке, что
и HTMLстраница), так и абсолютный путь.
var request = new XMLHttpRequest();
В первой строке создается новая переменная запро
са (request) на основании встроенного объекта XMLHttp
Request. Данный объект позволяет отправлять асинхрон
ные ajaxзапросы.
В следующей строке настраивается функция onrea
dystatechange объекта request, которая будет автомати
чески вызвана после отправки запроса. Функция будет
вызвана независимо от успешности выполнения запроса,
поэтому первое, что необходимо сделать, это проверить
результат: поле readyState хранит информацию о готов
ности ответа, а поле status — код ответа. Поле response
Text запроса хранит текст, полученный с сервера. Функ
ция обработки parseMap будет рассмотрена дальше в этой
главе.
Для отправки запроса необходимо воспользоваться
функцией open:
request.open("GET", path, true);
Первый параметр говорит об используемом методе.
В данном случае можно использовать методы «GET» или
«POST». Ключевое отличие заключается в том, что функ
ция «GET» передает все параметры прямо в URL запроса,
а функция «POST» — в теле запроса.