Объединение Easel.js и Box2d на Canvas

в 19:13, , рубрики: javascript, переводы

Один из наиболее сложных аспектов создания нашей игры заключался в том, чтобы совместить две очень крутые библиотеки: 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

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js