Один из наиболее сложных аспектов создания нашей игры заключался в том, чтобы совместить две очень крутые библиотеки: Easel.js и Box2dWeb. В данном материале мы рассмотрим основы создания главных игровыч объектов игры так, что вы сможете перевести box2d размеры в систему X, Y, и параметры вращения предметов на дисплее в easel.
Прежде чем приступить к данной статье, предполагается, что у вас есть базовые знания о том, как работают box2d и easel. Если вы не знакомы с работой мира box2d, пожалуйста, прочитайте материалы по box2d от Сета Лэда. Если вы не знакомы с работой easel, то вам необходимо ознакомиться с документацией, чтобы вы поняли, как добавлять предметы на сцену и изучили всю иерархию дисплея (подсказка: она имеет несколько общих аспектов с Flash программированием).
Ну, давайте углубимся в подробности. Мы собираемся создать простую демонстрацию падающих розовых птиц.
Посмотреть в браузере — Скачать исходный код
Поскольку мы уже понимаем основы работы Easel и Box2d, мы пропустим установочный код и углубимся в процесс совмещения двух библиотек. Если вы хотите вспомнить информацию, просто загрузите демонстрационный zip архив или просмотрите исходный код на странице демонстрации.
Сейчас в Easel достаточно легко добавлять объект на сцену в определённом положении. Вот как мы добавляем птиц на экран исходя из цикличной функции.
Заметьте, что все вставки кода из ниже-приведённых являются нефункциональными отрывками из demo.js. Чтобы получить рабочий код, необходимо загрузить zip архив.
var tick = function(dt, paused) {
birdDelayCounter++;
if(birdDelayCounter % 10 === 0) { // Задержка, птицы не производятся на каждом фрейме
birdDelayCounter = 0;
birds.spawn();
}
}
var spawn = function() {
var birdBMP = new Bitmap("images/bird.png");
birdBMP.x = Math.round(Math.random()*500);
birdBMP.y = -30;
birdBMP.regX = 25; // Важно установить начальную точку к центру изображения
birdBMP.regY = 25;
stage.addChild(birdBMP);
}
Это кажется достаточно знакомым. С помощью этого кода птица добавляется на сцене в выбранном наугад Х положении на верху полотна. Сам по себе объект достаточно разносторонний. Вы можете скопировать его положение, сдвинуть его и т.д. Однако, если вы хотите применить физические законы к своему объекту, вам нужно послать его в box2d.
regX и regY (начальные точки) важны, когда вы привязываете объект easel к box2d. Это связано с тем, что box2d объекты имеют начальное положение в центре в отличие от положения вверху слева у easel объектов.
Итак, наши объекты уже добавлены на сцену, пора послать их в box2d для дальнейших впечатляющих действий.
box2d.createBird(birdBMP);
var createBird = function(skin) {
var birdFixture = new b2FixtureDef;
birdFixture.density = 1;
birdFixture.restitution = 0.6;
birdFixture.shape = new b2CircleShape(24 / SCALE); // Ширина bird.png разделена мировым масштабом для правильного размера
var birdBodyDef = new b2BodyDef;
birdBodyDef.type = b2Body.b2_dynamicBody;
birdBodyDef.position.x = skin.x / SCALE; // Разделите skin x и y на box2d масштаб для получения нужной позиции
birdBodyDef.position.y = skin.y / SCALE;
var bird = world.CreateBody(birdBodyDef);
bird.CreateFixture(birdFixture);
bodies.push(bird);
}
С помощью вышеприведённого кода создаётся круглое box2d тело в том же положении и того же размера как и bitmap. К сожалению, изображение птицы не привязано к box2d объекту. Без debug canvas вы не сможете увидеть круглый box2d объекта, и птица останется неподвижной. Как мы заставляем изображение следовать положению тела box2d?
...Actors! Actors являются основной частью визуальной box2d демонстрации. В основном, это они вынуждены двигаться во время игрового цикла и переводить метрические позиции box2d тел обратно в пиксельные координаты. Давайте создадим это.
var actor = new actorObject(bird, skin);
bird.SetUserData(actor); // Установите actor как данные о теле так, чтобы мы могли получить доступ к ним, когда нам необходимо
var actorObject = function(body, skin) {
this.body = body;
this.skin = skin;
this.update = function() { // перевод box2d координат в пиксели
this.skin.rotation = this.body.GetAngle() * (180 / Math.PI);
this.skin.x = this.body.GetWorldCenter().x * SCALE;
this.skin.y = this.body.GetWorldCenter().y * SCALE;
}
actors.push(this);
}
Это основной пример actor объектов, если бы вы хотели, то вы могли бы расширить его с помощью почти любых показателей (идентификаторов и т.д.). Мы определили участника для box2d объекта и нам необходимо обновить его во время физического цикла.
// перед world.step
for(var i=0, l=actors.length; i<l; i++) {
actors<i>.update();
}
Изображение теперь отображает всё, что делает box2d тело в рамках моделирования физических процессов.
Если вы хотите удалить тело и его изображение в определённой точке, вы можете добавить тело в массив. Тела должны быть удалены перед каждым шагом.
// до world.step
for(var i=0, l=bodiesToRemove.length; i<l; i++) {
removeActor(bodiesToRemove<i>.GetUserData()); // get the actor object in the user data of the body and send to removeActor function
bodiesToRemove<i>.SetUserData(null);
world.DestroyBody(bodiesToRemove<i>);
}
// после world.step
if(bodies.length > 30) {
bodiesToRemove.push(bodies[0]);
bodies.splice(0,1);
}
var removeActor = function(actor) {
stage.removeChild(actor.skin);
actors.splice(actors.indexOf(actor),1);
}
Наконец у нас получилось! Вы можете совершить много значительных действий, если вы понимаете, как работают box2d фильтры при столкновении, обнаружение выхода за пределы и т.д. Я надеюсь, что мы в дальнейшем ознакомимся больше с этим материалом.
Посмотреть в браузере — Скачать исходный код
Author Justin Schrader
www.luxanimals.com/blog/article/combining_easel_box2d
Автор: dsderror