Skip to content

Latest commit

 

History

History
1628 lines (914 loc) · 70.4 KB

documentation.md

File metadata and controls

1628 lines (914 loc) · 70.4 KB

Содержание:

  1. DOM
  2. Математические операции
  3. Основы j2Ds
  4. Локальное хранилище
  5. Размеры экрана и fullScreen()
  6. Минимальный код
  7. Количество кадров в секунду (FPS)
  8. Игровые состояния
  9. Сцена
  10. Слои
  11. Виды (ViewPorts)
  12. Музыка
  13. Кисть
  14. Устройство ввода
  15. Базовая нода
  16. Прямоугольник
  17. Окружность
  18. Линия
  19. Текст
  20. Спрайт-карта и анимация
  21. Анимированные объекты
  22. Ресурсы
  23. События
  24. Триггеры
  25. Ввод текста с клавиатуры
  26. Шаблоны текстур
  27. Измерение FPS и игре
  28. Отладка и ошибки
  29. Более сложный пример

DOM

Для обработки DOM элементов в структуре HTML есть специальные упрощения:

var dom = j2Ds.getDOMManager();

Для доступа к объектам по id:

dom.id('id')

Для доступа по name:

dom.name('name')

Для доступа по тегу:

dom.tag('div')[x]

, где x - порядковый номер найденного элемента

Если необходимо корректно присоединить к документу какой-либо элемент DOM:

var div = document.createElement('div');
div.innerHTML = '<b>Меня присоединили</b>';

dom.attach(div[, parent]);

, где div - созданный элемент любого типа, parent - необязательный агрумент, если нужно присоединить элемент к другому элементу, например:

dom.attach(div, dom.id('customDIV'));

Математические операции

В j2Ds все операции над координатами и размерами рекомендуется использовать посредством соответствующих классов или объектов. Получить к ним доступ можно при помощи Менеджера математики:

var math = j2Ds.getMathManager();

Для задания целочисленных координат можно использовать объект:

math.v2i(0, 0)

Для задания вещественных координат:

math.v2f(0.0, 0.0)

Для округления до целого числа можно использовать:

parseInt(14.5)

или:

math.toInt(14.5)

или:

Math.ceil(14.5)

Для Рандомизации числа:

var num = math.random(0, 5);

Для Рандомизации, к примеру, от -15 до 15:

var num = math.random(-15, 15 [, omitZero]);

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

Есть возможность получить рандомный цвет стандартными средствами:

var min = 200, // минимальная граница
    max = 255, // максимальная граница
    alpha = 1; // прозрачность от 0 до 1

    var color = math.rndColor(min, max, alpha);

Для перевода градусов в радианы:

var num = math.rad(45); // 45'

Примечание: для быстрого доступа к этим функциям можно создать ссылки на них:

var v2f = j2Ds.getMathManager().v2f;
var random = j2Ds.getMathManager().random;
/* и др. */

Основы

Менеджер в j2Ds - это специальный объект, инициализирующийся командой j2Ds.get[NameManager], где NameManager - имя менеджера для работы.

Нода в j2Ds - это объект определенного типа, наследующий те или иные свойства другой (или нескольких) ноды.

j2Ds - Глобальный объект, дающий доступ к API движка.

Доступные для использования Менеджеры:

  • Менеджер сцены: getSceneManager()
  • Менеджеры управления
    • getIO
    • getTouchIO
  • Менеджер игровых состояний: getGameStateManager()
  • Менеджер слоев: getLayerManager()
  • Менеджер текстур: getTextureManager()
  • Менеджер устройства отображения: getDeviceManager()
  • Менеджер аудио: getAudioManager()
  • Менеджер хранения данных: getMemoryManager()
  • Менеджер видок (камер): getViewManager()
  • Менеджер расчетов FPS и оптимизации: getFPSManager()
  • Менеджер для работы с DOM: getDOMManager()
  • Менеджер векторов и математики: getMathManager()
  • Менеджер рисования (кисть): getPaintManager()
  • Менеджер обработки ошибок: getErrorManager()
  • Менеджер рисования: getPaintManager()
  • Менеджер триггеров: getTriggerManager()

В процессе выполнения игрового цикла вам доступны следующие переменные:

j2Ds.dt // Фактор "Delta Time"

Для того, чтобы просмотреть структуру объекта, можно выполнить команду:

console.log(j2Ds);

Локальное хранилище

Для хранения информации есть соответствующий объект:

var myLocal = j2Ds.createLocal('test');

, где 'test' - это уникальный id для экземпляра хранилища. Уникальный идентификатор нужен для того, чтобы хранить идентичные поля.

Для сохранения информации:

myLocal.save('myName', 'Skaner');

Для сохранения ноды/объекта:

myLocal.saveNode('myNode', idOfNode);

, где idOfNode - объект или нода.

Для проверки существования переменной в хранилище:

myLocal.is('myName'); // true/false

Для загрузки переменной:

myLocal.load('myName'); // Skaner

Для загрузки объекта:

myLocal.loadNode('myNode'); // Object "idOfNode"

Device

Для определения размера экрана, доступного для развертывания игры, можно использовать объект:

var device = j2Ds.getDeviceManager();

device.width     // ширина экрана
device.height    // высота экрана

Минимальный игровой код

Чтобы подготовить страницу для организации игрового приложения, необходимо наличие обязательных элементов:

  1. Скрипт движка
  2. Функция инициализации сцены
  3. Функция, описывающая игровое состояние

Код ниже представляет минимально необходимый код:

<!DOCTYPE html>
<html>
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta name="viewport" content="width=device-width,user-scalable=no" />
  <script type="text/javascript" src="j2ds/j2ds.js"></script>
  <title>Пример игрового кода</title>
 </head>
 <body>

<script type="text/javascript">

// Объект сцены для быстрого доступа
var scene = j2Ds.getSceneManager();

// вектор для быстрого доступа
var v2df = j2Ds.getMathManager().v2f;

// Менеджер игровых состояний
var mgs = j2Ds.getGameStateManager();

// инициализация сцены
scene.init(640, 480);

// Игровое состояние myGame
mgs.add('myGame', function () {
 // Очищаем сцену
 scene.clear();

 /* Вся игровая логика происходит тут */

});

// После описания игрового состояния, оно не будет выполняться, пока игра не будет запущена.
// Для этого используется команда start:
scene.start('myGame', 30); // Второй параметр - FPS
</script>

 </body>
</html>

FPS

В игре вам часто может потребоваться ограничить Количество кадров в секунду, чтобы игра выполнялась на одинаковой скорости при разных частотах процессора. Для этого необходимо при старте сцены указать требуемое ограничение FPS:

scene.start('Game', 30); // Старт игры с 30 fps

Кроме этого, вам так же доступен фактор Delta Time

j2Ds.dt // DeltaTime

Игровые состояния

В j2Ds для обработки игровой логики используется понятие "игрового состояния". Игровое состояние - это функция, которая выполняется FPS количество раз.

Для доступа к созданию игровых состояний и их использования есть специальный менеджер игровых состояний:

var mgs = j2Ds.getGameStateManager();

В игровых состояниях описывается вся игровая логика, игровые уровни, меню и поведение всех основных объектов.

Чтобы создать игровое состояние

Пример игрового состояния:

mgs.add('myGame', function() {
 /* Игровая логика */
}, function() {
 /* Команды, выполняемые лишь раз, при старте игрового состояния */
});

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

// Игровое состояние 1
mgs.add('level1', function() {
 if (j2Ds.io.isKeyPress('SPACE')) {
  j2Ds.scene.setGameState('level2');
 }
}, function() {
 console.log('Нажмите пробел для перехода во второе игровое состояние');
});

// Игровое состояние 2
mgs.add('level1', function() {
 if (j2Ds.io.isKeyPress('SPACE')) {
  j2Ds.scene.setGameState('level1');
 }
}, function() {
 console.log('Нажмите пробел для перехода в первое игровое состояние');
});

// Стартуем сцену с игровым состоянием 1
j2Ds.scene.start('level1', 25); // 25 fps

Сцена

Сцена - основная нода игрового менеджера.

// для облегчения доступа
var scene = j2Ds.getSceneManager();

Инициализация

Чтобы инициализировать сцену, используется команда:

var width = 640,  // ширина
    height = 480, // высота
    canDeactivate = false;
scene.init(width, height[, canDeactivate]);

, где canDeactivate - флаг, которым можно запретить движку отключать свою работу при деактивации окна. Если установить его, как false, то движок не будет отключаться. По умолчанию - true.

Примечание: Даже если указать третьим параметром false, то события scene:activate/deactivate будут срабатывать. Хотя движок и не будет отключаться. Удобно для ручного управления

Если у вас уже есть подготовленная HTML5 страница, на которой имеется canvas, вы можете привязать сцену к нему, не нарушая структуры самой страницы. Для это есть команда:

var id = 'id_of_canvas'; // id элемента
scene.initCanvas(id[, canDeactivate]);

Чтобы развернуть игру на весь экран есть специальная команда:

scene.fullScreen(true);

Примечание: команда работает только после инициализации игровой сцены командой scene.init().

Есть еще один метод для того, чтобы развернуть игру на весь экран:

scene.fullScale(true);

Примечание: команда работает только после инициализации игровой сцены командой scene.init().

Старт

Чтобы начать игровой процесс, используется команда j2Ds.scene.start():

 scene.start('gameState', 25); // 25 fps

Смена игрового состояния

Для смены текущего игрового состояния на любое другое:

scene.setGameState('newGameState'); // мгновенно переключится на GameState2

Примечание: newGameState - имя игрового состояния, созданного через менеджер игровых состояний.

Если вам нужно узнать имя текущего игрового состояния, можно воспользоваться командой:

scene.getGameState()

Очистка сцены

В игровом состоянии, если вы отрисовываете объекты, сцену нужно очищать перед отрисовкой, чтобы не возник эффект "рисования":

scene.clear();

Вы так же можете установить параметр автоматической перерисовки сцены:

scene.setAutoClear(true/false);

Примечание: setAutoClear() включает автоматическую очистку только основной сцены. Созданные вручную слои не очищаются автоматически

Автоматическая отрисовка объектов

При создании игры вы можете столкнуться с тем, что вам придется вручную рисовать объекты, иногда это удобно. Для каждого объекта типа "Node" есть соответствующий метод "draw()", но если вы желаете, вы можете указать движку, чтобы он автоматически отрисовывал объекты:

scene.setAutoDraw(true/false)

Примечание: Если этот параметр не установлен, для отрисовки объектов потребуется вызов метода draw() для каждого объекта.

Слои (Layers)

Для оптимизации производительности и снижения затрат на отрисовку статических объектов j2Ds поддерживает возможность создания и обработки слоев.

var scene = j2Ds.getSceneManager();
var layers = j2Ds.getLayerManager();

Сцена, как слой

Объект scene является центральным слоем. Для доступа к слою сцены есть метод:

scene.getLayer().метод()

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

Новые слои можно добавлять как поверх сцены, так и позади. Для определения глубины слоя используется индекс позиции:

// Создание слоя с именем background и индексом позиции '-1',
// Что означает, что слой будет располагаться позади основного слоя
// на -1 уровень
layers.add('background', -1);

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

Доступ к слою

Для доступа к слою и его методам и свойствам используется команда:

layers.layer('background').метод

Либо можно завести переменную для быстрого доступа при создании слоя:

var myLayer = layers.add('background', -1);

И затем доступ можно осуществлять как первым методом, так и:

myLayer.метод()

Заливка слоя

Для заливки слоя одним цветом:

layers.layer('background').fill('blue');

Скрыть/показать слой

Если слой необходимо скрыть или показать:

layers.layer('background').setVisible(true/false);

Прозрачность слоя

Для задания прозрачности слою есть команда:

setAlpha(0.5);

Чтобы получить прозрачность:

getAlpha()

Перемещение слоя

Так же слой можно перемещать вперед и назад:

var index = 1; // переместить слой спереди сцены на 1 уровень
layers.layer('background').setIndex(index);

Методы рисования

Для слоев так же актуальны следующие методы:

layers.layer('background').clear();
                          .clearNode(idNode);
                          .clearRect(pos, size);

Вы так же всегда имеете доступ к контексту слоя посредством функции onContext:

layers.layer('background').onContext(function(context){
 context.fillStyle = 'black';
 context.fillRect(0, 0, 25, 25); // нарисует черный квадрат
});

Пример заливки слоя градиентом:

layers.add('back', -1);
layers.layer('back').onContext(function (context) {
 textureManager.templates.gradientL(context,
                                   v2f(scene.width, scene.height),
                                   ['black', 'rgba(0,0,0,0)', 'black']);
});

Примечание: textureManager.templates.gradientL() - это функция из набора шаблонов создания текстур.

Удаление слоя

Если требуется удалить слой:

layers.layer('background').destroy();

Примечание: дважды добавить слой с одним и тем же именем невозможно.

Настройки контекста

При необходимости вы можете задавать настройки контексту напрямую через метод setContextSettings:

Следующий пример задает контексту сцены настройки, отображающие тени от всех Нод:

scene.getLayer().setContextSettings({
 'shadowColor' : '#FF8686',
 'shadowBlur' : 0.5,
 'shadowOffsetX' : 1,
 'shadowOffsetY' : 1
})

Примечание: настройки задаются для каждого слоя отвельно

Виды (ViewPorts)

В j2Ds есть аналог камер, которые можно создавать, двигать и фокусировать.

Для доступа к Видам используется Менеджер Видов:

views = j2Ds.getViewManager();

Чтобы добавить Вид:

var name = 'myView',     // Имя
    pos = v2f(60, 0); // Позиция

view.add(name[, pos])

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

Для обращения к Виду есть команда get:

view.get('myView').метод();

Либо при создании можно объявить ссылку на него:

var myView = view.add('myView');

и затем:

myView.метод();

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

scene.getView().метод();

Так же к основному виду можно обратиться по имени 'sceneView':

view.get('sceneView').метод();

Позиционирование

Для позиционирования камер есть соответствующие команды:

var pos = v2f(15, 50);
setPosition(pos);

Если требуется позиционирование только по одной координате:

setPosition().x = 15;  // x
setPosition().y = 200; // y

Для непрерывного движения камеры:

move(v2f(1, 0)); // будет двигать камеру по X координате на 1 пиксель

Для получения позиции Вида (камеры):

getPosition() - v2f-объект

Музыка (Звуки)

В своей игре вы так же можете использовать звуковое сопровождение. Для этого в j2Ds предусмотрен соответствующий Менеджер:

var snd = j2Ds.getAudioManager();

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

Для управления в нем предусмотрены следующие методы:

var id = 'audioStep', // звук шагов
    files = ['audio/step.mp3', 'audio/step.ogg']; // Массив с файлами
    volume = 0.5; // Начальная громкость
snd.load(id, files);

Так как не все форматы поддерживают разные браузеры, то предпочтительно использовать два формата: mp3 и ogg. Подробнее о поддержках форматов вы можете посмотреть в интернете.

Чтобы обратиться к элементу, его можно инициализировать как ссылку в начале, присвоив результат команды load переменной, либо использовать get:

var audioStep = snd.load(id, files); // Так

snd.get('audioStep').метод(); // либо так

Воспроизведение

Для однократного воспроизведения звука теперь достаточно просто вызвать метод play():

audioStep.play(unlock); // unlock нужен, если требуется принудительное воспроизведение, параметр необязательный

Для циклического воспроизведения:

audioStep.loop();

Остановка воспроизведения

Чтобы приостановить воспроизведение:

audioStep.pause(lock); // lock нужен, если требуется заблокировать файл для воспроизведение, параметр необязательный

Для полной остановки воспроизведения:

audioStep.stop(lock); // lock нужен, если требуется заблокировать файл для воспроизведение, параметр необязательный

Примечание: Если вызвать pause() а затем play(), то воспроизведение начнется с места остановки, если stop(), то сначала.

Вы в любой момент можете проверить текущее состояние воспроизведения:

audioStep.getState() - play | pause | stop

Громкость

Если необходимо, вы можете изменить громкость воспроизведения любого файла:

var vol = 0.2; // Значение громкости может варьироваться от 0 (нет звука) до 1 (максимум)

audioStep.setVolume(vol)

Чтобы получить громкость файла:

audioStep.getVolume()

Блокировка воспроизведения

Каждый метод (play, pause, stop) может принимать один необязательный параметр, принуждающий выполнить команду. Например, если в игровом цикле вы вызовите метод loop(), то остановить файл командой stop() не получится. Чтобы остановить зацикленное воспроизведение нужно воспользоваться командой stop(true) с параметром true, который заблокирует файл для воспроизведения. Заблокированный файл теперь можно будет воспроизвести либо командой play(true), либо указать:

setLock(false); // Разблокировать файл, true - заблокировать.

Заблокированный файл нельзя воспроизвести без параметра true.

Примечание: метод loop() не принимает параметра блокировки, только play(), pause(), stop().

Глобальные команды

Вы так же можете воспользоваться глобальными командами воспроизведения, остановки и паузы (за исключением loop). Глобальная команда отличается тем, что она срабатывает сразу на всех файлах и вызываются из самого Менеджера.

snd.stop(lock); // остановить все звуковые файлы

snd.pause(lock); // поставить все файлы на паузу

snd.play(unlock); // воспроизвести всё

Кисть

Иногда бывает так, что вам требуется вывести на сцену несложный объект или текст, и нет необходимости создавать для этого целый объект типа Нода. Именно для этих целей служит специальный Менеджер рисования:

var paint = j2Ds.getPaintManager();

Он позволяет вам отображать следующие объекты:

  • Прямоугольники
  • Текст
  • Изображение

Прежде, чем вывести какой-либо объект, вам нужно установить стиль для отрисовки:

Устройства ввода

Клавиатура

Для удобства работы с клавиатурой, тачскрином и мышью в j2Ds есть специальный объект:

var io = j2Ds.getIO();

Чтобы отслеживать нажатия клавиш на клавиатуре, есть специальные методы:

var key = 'UP'; // клавиша - это обычная строка

io.isKeyPress(key)
     .isKeyDown(key)
     .isKeyUp(key)

Все методы возвращают true/false в зависимости от состояния клавиши.

Пример:

if (io.isKeyPress('SPASE')) {
 console.log('Нажатие клавиши "Пробел"');
}

Примечание: чтобы это сработало, проверки должны выполняться в пределах игровых состояний.

Так же, чтобы узнать сканкод клавиши, которая нажата в данный момент, существует специальная переменная:

console.log(io.anyKey);

Чтобы получить список доступных для работы клавиши, есть функция:

var array_of_keys = io.keyList();

console.log(array_of_keys);

keyList() возвращает массив, в котором каждый элемент - это клавиша, которую можно использовать для проверки на реакцию.

Мышь

Для работы с мышью в объекте io существуют специальные свойства и методы.

Чтобы проверить, что нажата та или иная кнопка мыши, можно использовать следующие идентификаторы:

LEFT - Левая КМ
RIGHT - Правая КМ
MIDDLE - Средняя КМ

И соответствующие события:

io.isMouseDown(ID); // Удерживание кнопки мыши
io.isMousePress(ID); // Однократное нажатие
io.isMouseUp(ID); // Отпускание кнопки

Примечание: ID - идентификатор кнопки мыши

Пример:

if (io.isMousePress('LEFT')) {
 console.log('Нажата левая кнопка мыши');
}

Если требуется отлавливать события колесика мыши, есть соответствующее событие:

io.isMouseWheel(ID) // Вращение колесика

, где ID - идентификатор направления:

UP - Вверх
DOWN - Вниз

Пример:

if (io.isMouseWheel('UP')) {
 console.log('Колесико крутится вверх');
}

Курсор мыши - это специальный объект, хранящий в себе координаты курсора мыши.

Чтобы узнать, где находится курсор мыши, можно использовать следующие команды:

io.getPosition() - вернет объект типа v2i с координатами X и Y.

Примечание: getPosition() вернет координаты с учетом смещения камеры.

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

Пример:

var scene = j2Ds.getSceneManager();
var io = j2Ds.getIO();

// Сдвинем камеру вправо на 100px
scene.setViewPosition(v2i(100, 0));

// Вернет позицию курсора внутри игрового мира.
// Если расположить курсор на 0,0 (самый левый угол),
// то позиция курсора по X будет 100 или больше.
console.log('Позиция курсора по X координате: ' + io.getPosition().x);

// Вернет позицию курсора, проецирующуюся на сцену
console.log('Позиция на canvas по X: ' + io.x);

Курсор над объектом

Если вам требуется узнать, находится ли курсор над каким-то объектом, есть функция:

io.onNode(a); // true/false

* С версии 0.6.4 этот метод может принимать массив объектов.

Примечание: a - любой объект, наследующий базовую ноду.

Внешний вид курсора

Если вам не нравится стандартный вид курсора, вы можете его изменить:

io.setCursorImage('my_folder/my_image.png');

Скрытие курсора

Если в вашей игре вам потребовалось скрыть или отобразить, есть соответствующая команда:

io.setVisible(true/false);

Чтобы узнать, скрыт ли курсор:

io.isVisible(); // true/false

Тачскрин

Для работы с устройствами, обладающими сенсорным экраном есть соответствующий Менеджер:

var touch = j2Ds.getTouchIO();

С помощью этого Менеджера вы можете отслеживать события тачскрина, такие как:

  • Касания
  • Жесты
  • Движения пальцев (стилуса)

Особо работа с Менеджером TouchIO не сильно отличается от работы с мышью, но есть свои особенности.

События, которые вы можете отслеживать внутри игрового цикла:

isTapDown() - удерживание пальца на сенсоре
isTapPress() - однократное касание (клик, тап)
isTapUp() - отпускание пальца (стилуса)

Эти события возвращают результат при касание пальцем. При этом при каждом из них позиция касания устанавливается по последнему пальцу. Для отлова множественных нажатий потребуется специальная функция:

getTouch() - получение всех прикосновений в текущий момент времени

Вернет false, если ничего не касается экрана. Если тачскрин фиксирует прикосновение, то объект вернет массив содержащий количество пальцев, участвующих в событии, а так же координаты каждого нажатия:

var gettingTouchs = touch.getTouch();

Выглядеть gettingTouchs будет так:

[
 {
  id : <порядковый номер прикосновения>,
  pos : {
         x : <X - координата>
         y : <Y - координата>
        },
  screenPos : {
               x : <X - координата>
               y : <Y - координата>
              }
 },
 ... ,
 {
  id : <порядковый номер прикосновения>,
  pos : {
         x : <X - координата>
         y : <Y - координата>
        },
  screenPos : {
               x : <X - координата>
               y : <Y - координата>
              }
 }
]

Если вам необходимо перебрать все прикосновения, можно сделать так:

var tList = touch.getTouch();

if (tList) {
 for (var i = 0, len = tList.lenght; i < len; i += 1) {
  console.log('Прикосновение '+tList[i].id+'; x: '+tList[i].pos.x+', y: '+tList[i].pos.y);
 }
}

Примечание: если вы хотите написать свой собственный обработчик для устройств ввода/вывода, вы можете просто не вызывать метод "getIO()"

Базовая нода

Базовая нода - это основной класс, который наследуется другими графическими объектами. Объект базовой ноды имеет множество методов и свойств, присущий другим объектам типа Node, и позволяет использовать их.

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

Создание

Чтобы создать объект BaseNode:

var pos = v2f(10, 10),  // позиция
    size = v2f(20, 20); // размер

// Создание базовой ноды
var a = scene.addBaseNode(pos, size);

Размер базовой ноде нужен для того, чтобы можно было корректно отображать Bounding-Box объектов.

Слои для отрисовки

Для переопределения слоя отрисовки используется команда:

a.setLayer('background');

Чтобы узнать, какой слой используется объектом:

var gettingLayer = a.getLayer();

Примечание: gettingLayer в данном случае содержит объект слоя.

Collision-box и Bounding-box

По умолчанию все объекты имеют collision-box для определения пересечений, равный их bounding-box, но collision-box можно переопределить командой:

offsetLeftTop = v2f(5, 5); // смещение вниз и вправо
offsetRightBottom = v2f(-10, -10); // уменьшение размера
a.resizeBox(offsetLeftTop, offsetRightBottom);

/* где-то внутри игрового состояния : */
a.drawBox();

Скрыть/показать объект

Чтобы скрыть/отобразить объект:

a.setVisible(true/false);

Проверить, видим ли объект:

a.isVisible(); // true/false

Прозрачность

Чтобы задать прозрачность объекту, используется команда:

a.setAlpha(0.5);

, где 0.5 - "сила" прозрачности. Аргумент принимает значения в диапазоне 0 - 1.

Примачание: если объект полностью прозрачен (невидим), isLookScene() все равно вернет true, если он в пределах видимости сцены.

Получить значение прозрачности:

a.getAlpha(); // числовой значение

Движение и позиция

Если необходимо двигать объект в направлении какой-либо позиции, используется команда:

var slow = 5; // замедление
a.moveTo(b.getPosition(), slow); // Объект a двигается к объекту b

Если требуется явно указать позицию объекта:

var pos = v2f(50, 900); // Позиция
a.setPosition(pos);

или:

a.setPosition(v2f(50, 900));

Для указания только одной координаты, можно ее вызвать:

a.setPosition().x = 15; // Установить позицию только по X
a.setPosition().y = 15; // Установить позицию только по Y

Чтобы двигать объект:

a.move(v2f(0, 1)); // Двигает объект вниз

Чтобы получить текущую позицию объекта:

var pos = a.getPosition();
console.log(pos.x, pos.y);

Размеры

Чтобы задать объекту нужный размер:

a.setSize(v2f(10, 10)); // Новый размер: 10x10 пикселей

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

a.setSize().x = 15;
a.setSize().y = 15;

Для получения размера:

a.getSize(); // v2f объект

Расстояние между объектами

Чтобы получить расстояние между двумя объектами:

var dist = a.getDistance(b);
console.log(dist);

Чтобы получить дистанцию по осям, есть функция:

var distX = a.getDistanceXY(b).x; // дистануия по оси X
var distY = a.getDistanceXY(b).y; // по оси Y

Пересечения

Чтобы проверить пересечения между двумя объектами:

a.isIntersect(b); // Вернет true, если объекты пересекаются

* С версии 0.6.4 этот метод может принимать массив объектов.

Видимость в пределах сцены

Чтобы узнать, попадает ли объект в камеру, "видит ли его камера":

a.isLookScene(); // если видим  true, иначе false

Вращение

Если нужно вращать объект:

a.turn(1); // вращает объект

Примечание: можно в качестве параметра указывать любое число - это скорость вращения. Если число положительное - по часовой стрелке, если отрицательное - против.

Чтобы задать угол вращения напрямую:

a.setRotation(45); // повернуть объект на 45 градусов

Чтобы двигать объект в соответствии с его углом поворота:

a.moveDir(speed);

, где speed - скорость перемещения

Для получения текущего угла вращения:

a.getRotation(); // угол вращения в градусах

Границы сцены

Так же может оказаться полезным проверка соприкосновения объекта с границами сцены и попытки выйти его за их пределы:

var isColl = a.isOutScene();

console.log(isColl); // Object
isColl.x; // Если < 0, то столкновение с левой границей, если > 0 - с правой
isColl.y; // Если < 0, то столкновение с верхней границей, если > 0 - с нижней
isColl.all; // Любой из вышеперечисленных

Отображение bounding-box

Чтобы отобразить bounding-box и collision-box объекта:

a.drawBox();

Примечание: bounding-box рисуется черным цветом, collision-box - желтым.

Прямоугольник

Наследует: BaseNode

Для создания прямоугольника:

var pos = v2f(0, 0),     // Позиция
    size = v2f(25, 40);  // Размер
    color = 'green';        // Цвет

// Создание поямругольной ноды
var a = scene.addRectNode(pos, size, color);

Так как объект прямоугольник графический, кроме метода 'drawBox()' для рисования box-ов у него есть еще один метод:

a.draw();

Он рисует созданный прямоугольник на соответствующий слой в соответствующей позиции.

Окружность

Наследует: BaseNode

Для создания окружности:

var pos = v2f(0, 0),     // Позиция
    radius = 10;            // Радиус
    color = 'green';        // Цвет

// Создание окружности
var a = scene.addCircleNode(pos, radius, color);

Так как объект Окружность графический, кроме метода 'drawBox()' для рисования box-ов у него есть еще один метод:

a.draw();

Он рисует созданную окружность на соответствующий слой в соответствующей позиции.

Линии

Наследует: BaseNode

В j2Ds есть возможность создавать объекты из линий:

var pos = v2f(50, 50), // Позиция
    scale = 1,            // Фактор увеличения масштаба. > 1 увеличение, < 1 уменьшение
    width = 2,            // Толщина линий
    color = 'black',      // Цвет линии
    flagFill = true,      // Флаг (true/false) заливки объекта
    colorFill = 'red';    // Если указан флаг заливки, можно назначить цвет

var points = [];          // Массив массивов точек

points = [ [0, 0], [10, 10], [20, 0], [10, -10], [0, 0] ];

var a = scene.addLineNode(pos, points, scale, color, width, flagFill, colorFill);

Для отрисовки объекта так же используется методов draw():

a.draw();

Текст

Наследует: BaseNode

Если требуется вывести текст в вашей игре, вы можете создать соответствующий объект TextNode:

var pos = v2f(50, 50), // Позиция
    text = 'Привет Мир!\nЭто будет уже с новой строки\nИ это тоже.',
    size = 15, // размер текста
    color = 'red', // Цвет текста
    family = 'sans-serif'; // Шрифт
    lineWidth = 4, // Ширина обводки текста
    lineColor = 'blue'; // Цвет обводки
var a = scene.addTextNode(pos, text, size, color, family, lineWidth, lineColor);

Если текст требуется изменить, есть команда:

a.setText('Новый текст');

Для получения текста:

a.getText(); // 'Новый текст'

Для задания нового размера текста:

a.setSize(18);

Чтобы узнать размер:

a.getSize(); // 18

Для вывода текста:

a.draw();

Если вам требуется выводить динамический текст, который часто изменяется и его не требуется обрабатывать (не важен размер или контейнер):

a.drawSimpleText('Пример вывода простого текста\nНовая строка поддерживается.' [,v2f(0, 0), colorText, lineColor]);

, где [,v2f(0, 0), color, lineColor] - необязательные параметры для нового цвета и новой позиции. Если их не указать, текст будет выводиться в позиции самого объекта с его цветом и обводкой.

Примечание: drawSimpleText() не изменяет стиль текста и его позицию, а так же сам текст.

Спрайт-карта

В j2Ds есть возможность использовать спрайты, как объекты, взаимодействующие с игровым миром, но для их создания требуется специально подготовленной изображение - спрайт-карта.

Пример спрайт-карты: sptiteMap

Формат такой спрайт-карты имеет только одно обязательное условия: кадры должны располагаться горизонтально!

j2Ds позволяет вам загружать такие спрайт карты через объект j2Ds.getTextureManager().

Для загрузки спрайт-карты есть специальная команда:

var textureManager = j2Ds.getTextureManager();

var imageMap = textureManager.loadImageMap('my_folder/my_image.png');

Этой командой изображение станет доступным для обработки внутри движка.

Кроме того, вы можете низкоуровневым способом создавать свои собственные спрайт-карты средствами движка. Для этого есть команда:

var width = 400,
    height = 100;

var createImg = function(context) {
 for (var i = 0; i < 400; i+=100) {
  context.fillStyle = j2Ds.math.rndColor(100, 250, 1);
  context.fillRect(i, 0, i+100, 100);
 }
}

var imageMap = textureManager.createImageMap(width, height, createImg);

Ну или же передать все параметры непосредственно в функцию:

var imageMap = textureManager.createImageMap(400, 100, function(context) {
 for (var i = 0; i < 400; i+=100) {
  context.fillStyle = j2Ds.math.rndColor(100, 250, 1);
  context.fillRect(i, 0, i+100, 100);
 }
});

Функция "конструктор" для текстуры принимает лишь один параметр - ссылку на контекст новой текстуры и сама же его воссоздает.

Но сам по себе объект imageMap ни с чем не может взаимодействовать, это просто подготовленный объект для взятия из него необходимых спрайтов или анимаций. Чтобы "извлечь" анимацию или картинку из него, есть команда:

var sourceX = 0,    // Позиция первого кадра по X
    sourceY = 0,    // Позиция первого кадра по Y
    sourceH = 60,   // Высота первого кадра
    sourceW = 30;   // Ширина первого кадра
    frameCount = 1; // Количество кадров, если это анимация

// Создание анимации
var anim = imageMap.getAnimation(sourceX, sourceY, sourceW, sourceH, frameCount);

Примечание: Теперь такую анимацию можно передать в качестве аргумента для вывода на слой/сцену. Примечание № 2: sourceX,Y,W,H не должны выходить за пределы изображения

Анимированные объекты

Наследует: BaseNode

Чтобы игра была насыщенней, в j2Ds есть возможность использовать не только прямоугольники и круги, вы так же можете использовать изображения из спрайт-карт.

Для создания спрайта существует команда:

var pos = v2f(10, 15);   // Позиция
    size = v2f(30, 60);  // Размер

var a = scene.addSpriteNode(pos, size, anim);

, где anim - анимация на основе спрайт-карты

Для отрисовки спрайта есть несколько методов:

// Чтобы нарисовать любой один кадр анимации
a.drawFrame(2); // Рисует второй кадр

// Для отрисовки анимации целиком
a.draw();

// Если нужно замедлить скорость анимации, можно в метод draw() передать кол-во кадров, которые будут пропускаться
a.draw(15); // При 30 fps анимация работает на скорость 30-15 FPS, то есть медленнее.

Если вы создали объект, и указали в качестве анимации 'anim1', и в процессе игры вам потребуется изменить анимацию (прим.: уничтожение врага - взрыв), есть команда:

a.setAnimation(amin2); // Присвоит анимацию anim2 спрайту.

Ресурсы

Ресурсами в j2Ds считаются любые файлы, будь то звук, картинка, или текстовый (бинарный) файл.

Для доступа к ресурсам в движке существует специальный менеджер:

var res = j2Ds.getResourceManager();

После этого в объекте res у вас будет доступно несколько методов:

Первый метод show:

var info = res.show();

console.log(info);

Метод show возвращает объект, содержащий три свойства:

  • added - добавлено внешних объектов
  • loaded - успешно загруженно объектов
  • failed - ошибок при загрузках объектов

Для получения прогресса загрузки (в процентах) есть метод getProgress:

var percent = res.getProgress();

console.log(percent); // integer

Так же вы всегда можете проверить, загружены ли все ресурсы:

var loaded = res.isLoaded();

console.log(loaded); // true/false

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

События

В j2Ds есть понятие - событие. Оно определяет какой-то определенный момент в выполнении программы, и позволяет при наступлении этого момента определить какое-либо поведение движка. На данные момент имеются следующие события (выполняются в порядке перечисления):

  • scene:beforeInit - перед инициализацией
  • scene:afterInit - после инициализации, но ДО формирования документа
  • dom:loaded - сразу же после формирования документа
  • scene:beforeStart - перед запуском игрового цикла
  • scene:afterStart - сразу же после его запуска

При работе игры в браузере, может возникнуть ситуация, что пользователю нужно будет переключиться на другую вкладку, к примеру, или закрыть всплывающее сообщение от сторонней программы, в этом случае игра приостанавливается (замирает). Но, кроме того, есть два события, которые срабатывают в этот момент:

  • scene:deactivate - потеря фокуса сцены (переключение вкладки, клик по другому элементу)
  • scene:activate - возвращение фокуса на сцену (клик по неактивной сцене, переключение на вкладку с игрой и т.д.)

Следующие два события срабатывают во время выполнения игры

  • writeMode:keyPress - при вводе любого символа с клавиатуры в write-mode режиме
  • scene:changedGameState - при смене игрового состояния командой setGameState

Примечание: событие changedGameState срабатывают в момент, когда игровое состояние уже изменено!

Аналогично два следующих события срабатывают во время выполнения игры:

  • engine:before - перед выполнением игрового цикла (перед первым кадром)
  • engine:after - после выполнения игрового цикла (после последнего кадра)

Чтобы назначить обработчик на события, в j2Ds если специальная команда addEvent:

j2Ds.events.addEvent('dom:loaded', function() { alert('Документ успешно загружен!') });

Эта команда добавит функцию в общий стек слушателя загрузки документа. Функций на добавление может быть любое количество.

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

j2Ds.events.addEvent('engine:before', function() { 'Выполняю игровой цикл' }, 'gameLoopRunning');

К обработчикам события 'engine:before' попадает функция с идентификатором 'gameLoopRunning', и если вам больше не требуется обработчик 'gameLoopRunning', вы можете его просто удалить:

j2Ds.events.destroyEvent('engine:before', 'gameLoopRunning');

Эта команда посмотрит в событие 'engine:before', и, если будет обнаружен обработчик с идентификатором 'gameLoopRunning', она его удалит.

dom:loaded

Важно знать, что если на момент назначения обработчика на событие 'dom:loaded' документ УЖЕ будет загружен, обработчик выполнится сразу же.

Например:

j2Ds.events.addEvent('dom:loaded', function() { alert('Документ успешно загружен!') });

Выведет сообщение либо сразу, если документ уже загружен, либо как только документ загрузится, то есть в любом случае.

Чтение клавиатуры

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

var io = j2Ds.getIO();

var textBuffer = ''; // буфер для текста

// устанавливаем обработчик события ввода символа
j2Ds.events.addEvent('writeMode:keyPress', function (symbol) {
 // дописываем введенный символ
 textBuffer += symbol;
 // если нажали клавигу "Backspace", то удаляем последний символ (коррекция ввода)
 if (io.isKeyPress('BACKSPACE')) {
  textBuffer= textBuffer.substring(0, textBuffer.length - 1);
 }
 // если нажали "Enter" - отправляем имя на сервер
 if (io.isKeyPress('ENTER') && textBuffer) {
  console.log(textBuffer);
  textBuffer= '';
 }
});

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

При этом важно, чтобы этот обработчик сработал, необходимо включить 'write-mode' объекта io:

io.setWriteMode(true);

После того, как ввод текста завершен и больше считывание клавиатуры не требуется, его можно отключить:

io.setWriteMode(false);

Чтобы проверить, включен ли режим ввода, есть функция:

io.isWriteMode()

Примечание: если write-mode движка не включен, обработчик не выполнится.

За один вызов функции-обработчика передается один символ. Поэтому для ввода желательно использовать какой-нибудь буфер или переменную.

Триггеры

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

var trg = j2Ds.getTriggerManager();

Чтобы создать триггер, существует команда add, которая вернет ссылку на созданный объект:

var name = 'logger',
    func = function() {
     console.log('Сработал триггер "logger"');
    };

var logger = trg.add(name, func);

Вы так же можете не создавать ссылку на объект, а обращаться к нему через get:

trg.get('logger').метод();

Если вам требуется запустить функцию лишь один раз за все время жизни игры, есть метод job:

var time = 2000; // 2 секунды
logger.job(time)

, где time - время задержки. Команда job выполнит команду лишь один раз сразу, как только наступит время выполнения.

Если же нужно выполнять команды циклически, есть команда loop:

var time = 5000; // 5 секунд
logger.loop(time);

, где time - период невыполнения команды. Что значит, что команды будут выполнять 1 раз в 5 секунд.

Если требуется просто подождать какое-то время, а затем просто запустить команды, чтобы они работали постоянно, есть команда run:

var time = 1000; // 1 секунда
logger.run(time);

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

Шаблоны текстурирования

В j2Ds вы можете вместо загрузки текстуры из файла создавать ее "на лету" командой createImageMap, или же закрасить слой по шаблону командой onContext, которые принимают лишь один аргумент - это контекст для отрисовки. Внутри этих функций вы можете использовать шаблоны текстурирования.

Начинается любой шаблон командой textureManager.templates.названиеШаблона, где "названиеШаблона" - это функция текстурирования:

  • textureManager.templates.ellips(context, v2f(width, height), color) - Рисует эллипс
  • textureManager.templates.fillRect(context, v2f(width, height), color) - Рисует прямоугольник закрашенный
  • textureManager.templates.strokeRect(context, v2f(width, height), color, lineWidth) - Рисует пустой прямоугольник
  • textureManager.templates.gradientL(context, v2f(width, height), colors [, izHorizontal]) - Рисует линейный градиент, colors - массив цветов
  • textureManager.templates.gradientR(context, v2f(width, height), v2f(x1, y1), r1, v2f(x2, y2), r2, colors) - Рисует радиальный градиент, colors - массив цветов

Пример использования:

scene.getLayer().onContext(function(context) { // Обращение к контексту слоя сцены
 textureManager.templates.fillRect(context, v2f(50, 50), 'red'); // нарисует красный квадрат
});

Измерение FPS в игре

На этапе разработке полезным бывает измерение FPS для оптимизации скоростей и расчета производительности вашей игры. Для этого вы можете воспользоваться специальным менеджером FPS:

var fps = j2Ds.getFPSManager();

Количество кадров будет рассчитываться для текущего игрового состояния.

Для получения значения fps:

fps.getFPS()

Пример вывода:

a.drawSimpleText('Текущий FPS: ' + fps.getFPS(), 'green');

Примечание: drawSimpleText() - метод объекта TextNode

Отладка и ошибки

Для отладки и отлова ошибок в j2Ds есть соответствующий менеджер:

var err = j2Ds.getErrorManager();

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

Примечание: если вы не инициализируете этот менеджер, вы не увидите ни одного сообщения об ошибке!

По-умолчанию движок будет пытаться выполнить любой код, который вы поместите в ваше игровое состояние, но при необходимости вы можете указать ему соответствующий режим работы:

var mode = 'neverShow'; // режим по-умолчанию
err.setMode(mode);

, где mode - режим работы менеджера.

Есть следующие режимы работы:

  • neverShow - движок пытается выполнить любой код, не выдавая сообщений об ошибках (установлен по-умолчанию)
  • onlyShow - при ошибках в консоль будет выводиться информация о них, но работа приложения не будет приостановлена
  • stopAndShow - при ошибке работа приложения останавливается, а в консоль выводится информация об ошибке

Примечание: предпочтительно на начальных этапах работы пользоваться режимом stopAndShow

Если вам требуется остановить выполнение приложения в каком-либо месте вы можете вызвать метод debug:

err.debug([text]);

, где text - необязательный аргумент, позволяющий вывести, при необходимости, любую информацию, объект или переменную.

При этом в консоль добавится сообщение о том, что достигнута точка останова.

При необходимости что-либо вывести в консоль предпочтительно использовать метод err.show:

err.show(x); // Выведет в консоль значение переменной x

Примечание: вы можете маркеровать сообщения любым удобным цветом

Более сложный пример: