Файл: Беляев С А - Разработка игр на языке JavaScript - 2016.pdf
Добавлен: 25.10.2018
Просмотров: 7600
Скачиваний: 136
46
Глава 2
ВОПРОСЫ ДЛЯ САМОПРОВЕРКИ
1. Какие существуют варианты построения игрового поля для
2Dигр?
2. Какая информация хранится в JSON, построенном с помощью
редактора карт Tiled?
3. Какие ключевые поля есть у слоев типа tilelayer и objectgroup?
4. Что такое менеджер карты? Какими полями он должен обла
дать?
5. Что такое AJAXтехнология? В чем ее особенность? Каким
встроенным объектом JavaScript она реализуется?
6. Зачем нужно считать количество загруженных изображений в
менеджере карты? Как количество загруженных изображений
используется в функции draw?
7. В методе parseMap создается новый объект tileset. Чем он от
личается от объекта, на основе которого создается? Что хранит
поле image?
8. Что делает встроенная функция setTimeout? Как ей пользо
ваться?
9. Какие параметры требует функция контекста drawImage?
10. Как вычислить в пикселах координаты (x, y) блока для отобра
жения из массива data при известном индексе блока в массиве?
11. Какие поля есть в объекте, предназначенном для отображения?
Чем он отличается от tileset?
12. Для чего нужно поле view в менеджере карты? Какими поля
ми обладает объект view? В каких методах изменяются и ис
пользуются его значения?
13. Объясните условие, приведенное в функции isVisible.
14. Какими полями обладает объект, создаваемый при разборе
объектов карты?
15. Что делает встроенная функция Math.floor?
УПРАЖНЕНИЯ
1. Напишите программу, обеспечивающую загрузку и
отображение нескольких слоев типа tilelayer.
2. В менеджере карт есть три поля imgLoadCount,
imgLoaded и jsonLoaded. Перепишите mapManager таким
образом, чтобы в нем было только одно поле loaded, кото
рое бы заменило эти три поля без потери функционально
сти, т. е. обеспечило разработчику понятный и полнофунк
циональный контроль загрузки изображений и JSON.
3. Модифицируйте объект tileset таким образом, что
бы не было необходимости создавать новые объекты для
отображения в функции getTile.
Г Л А В А 3
ОТОБРАЖЕНИЕ ОБЪЕКТОВ
Отображение объектов на холсте подразумевает опи
сание объекта, определение его местоположения и отобра
жение. В случае размещения уникальных объектов разра
ботчику необходимо каждый из них создать для последую
щего отображения, но в большинстве игр объект одного и
того же типа может встретиться несколько раз, тогда пос
ле описания объекта появляется задача его тиражирова
ния и размещения копий в заданных местах. Размещение
копий тоже может выполняться поразному: объекты мо
гут размещаться дизайнером игры при подготовке карты
либо создаваться на этапе выполнения игры в ответ на дей
ствия пользователя. В данной главе будет рассмотрен са
мый сложный для разработчика случай, когда дизайн
карты отделен от игры — дизайнер на этапе подготовки
карты сам определяет, где и какие объекты должны раз
мещаться.
Следующий шаг — анимация объектов, которая вклю
чает отображение рисунков в заданной последовательно
сти с учетом логики работы игры. Чем сложнее анимация,
тем больше рисунков придется использовать для отобра
жения. Практика показывает, что для игры средней слож
ности может потребоваться загрузка более 1000 файлов в
браузер. Загрузка большого количества мелких файлов
требует значительно большего времени, чем загрузка не
скольких объемных файлов. Соответственно, можно пред
ложить ускорение процесса загрузки множества изобра
жений, если разместить их в одном файле.
48
Глава 3
3.1.
СОЗДАНИЕ ОБЪЕКТОВ ИГРЫ
Большинство объектов игры обладают общими свой
ствами, такими как координаты на холсте и размеры.
Удобно эти свойства описать один раз, чтобы потом ис
пользовать во всех создаваемых объектах. При разработ
ке на объектноориентированных языках, таких как Java
или C++, C#, можно воспользоваться наследованием для
классов. В случае JavaScript воспользуемся похожими, но
другими механизмами. Прежде всего, опишем объект,
который будет хранить общие свойства [12], [13].
var Entity = {
pos_x: 0, pos_y: 0, // ïîçèöèÿ îáúåêòà
size_x: 0, size_y: 0 // ðàçìåðû îáúåêòà
}
В объекте Entity определены координаты (pos_x, pos_y)
и размеры объекта (size_x, size_y). Рассмотрим способы
создания объектов, которые будут иметь общие свойства с
Entity. Следующий создаваемый объект назовем Player
(игрок). Это тот самый игрок, который инициализирует
ся в менеджере игры parseEmtities (п. 2.2). На данном эта
пе рассмотрим только одно свойство игрока — запас жиз
ненных сил (lifetime).
Способ 1. Внешнее добавление полей и функций.
var Player = Object.create(Entity);
Player.lifetime = 100;
В первой строке создается новая переменная Player,
которая получает все свойства и методы, описанные в
объекте Entity. Важно, если в объекте Entity в качестве
полей разработчик добавит объекты, то они станут общи
ми для Player и Entity, соответственно, изменение этих
полейобъектов в Player будет изменять их в Entity и на
оборот. Именно по этой причине предлагается в объекте
Entity создавать поля, хранящие числа, строки или логи
ческие переменные, но не объекты. В приведенном при
мере Entity хранит четыре числовых поля.
Отображение объектов
49
Во второй строке в объект Player добавляется новое
поле (lifetime), которому присваивается значение 100.
Аналогичным способом можно добавить функции.
Данный способ применим, если объект нужно создать
только один раз. В случае многократного использования
возникнет существенное дублирование кода.
Способ 2. Ручная настройка необходимых полей.
var Entity = {
pos_x: 0, pos_y: 0, // ïîçèöèÿ îáúåêòà
size_x: 0, size_y: 0, // ðàçìåðû îáúåêòà
createPlayer: function(lifetime) {
var Player = Object.create(this);
Player.lifetime = lifetime;
return Player;
}
}
В приведенном коде первые две строки — поля Entity,
описанные в начале главы. Следующей строкой описана
функция createPlayer, в которой настраиваются поля объ
екта Player. В качестве параметра передается переменная
lifetime, в первых двух строках функции повторяется пер
вый способ создания Player, только значение поля lifetime
задается не числом, а параметром функции.
return Player;
Приведенная команда возвращает создаваемый объект.
Данный способ в отличие от способа 1 позволяет мно
гократно использовать функцию создания объекта и не
приводит к дублированию кода, однако при таком подхо
де существенно увеличивается Entity и при необходимости
создания большого количества разных объектов код про
граммы станет трудночитаемым.
Способ 3. Автоматическая настройка необходимых
полей.
var Entity = {
pos_x: 0, pos_y: 0, // ïîçèöèÿ îáúåêòà
size_x: 0, size_y: 0, // ðàçìåðû îáúåêòà
extend: function (extendProto) { // ðàñøèðåíèå ñóùíîñòè
50
Глава 3
var object = Object.create(this); // ñîçäàíèå íîâîãî îáúåêòà
for (var property in extendProto) { // äëÿ âñåõ ñâîéñòâ íîâîãî
// îáúåêòà
if (this.hasOwnProperty(property) || typeof object[property] ===
'undefined') {
// åñëè èõ íåò â ðîäèòåëüñêîì - äîáàâèòü
object[property] = extendProto[property];
}
} // Êîíåö öèêëà for
return object;
} // Êîíåö ôóíêöèè extend
};
var Player = Entity.extend({ lifetime: 100 });
В приведенном коде описано создание двух перемен
ных — объектов Entity и Player. Поля объекта Entity по
вторяют поля из 1 и 2 способов, но появляется новая функ
ция extend, которая в качестве параметра принимает объ
ект (extendProto). Разберем каждую строку метода extend.
var object = Object.create(this);
Создается новая переменная object, в которую копи
руются все поля и функции Entity.
for (var property in extendProto)
Цикл for отличается от рассмотренных в предыдущих
главах. В данном случае создается новая переменная pro
perty, которая последовательно перебирает все поля и
функции объекта extendProto.
if (typeof object[property] === 'undefined')
Затем следует условие, изменение которого существен
но меняет логику функции extend. В данном случае прове
ряется, что property у object не определено: тип (typeof) поля
object (object[property]) неопределен (=== 'undefined').
Если данную проверку убрать, то создаваемый объект мо
жет изменить поля или функции, общие для Entity.
object[property] = extendProto[property];
Значение поля или функции с именем property копи
руется из extendProperty в object.
return object;