Рисование пользовательских полигонов в Box2D

Я делаю Flash-игру и столкнулся с очень странной проблемой при попытке нарисовать многоугольник в Box2D.

Вот код, который я использую:

var fixtureDefs:Array = new Array();

...

var fDef:b2FixtureDef = new b2FixtureDef();
fDef.density = 0;
fDef.shape = new b2PolygonShape();
b2PolygonShape(fDef.shape).SetAsArray(vertexArray);
fixtureDefs.push(fDef);

//This gets repeated several times, so that at the end you get a body consisting of several convex shapes.

...

var bD:b2BodyDef = new b2BodyDef();
bD.type = b2Body.b2_staticBody;
bD.position.Set(300/Constants.RATIO,200/Constants.RATIO);

var body:b2Body = Constants.world.CreateBody(bD);

...

for each(var fD:b2FixtureDef in fixtureDefs) {
body.CreateFixture(fD);
}

Где vertexArray — допустимый массив, содержащий 4 вершины b2Vec2, составляющих выпуклую форму.

Проблема в том, что когда я тестирую, коллизии не работают для этого тела. Большинство других объектов — враги, управляемые пользователем персонажи — проходят насквозь, как будто тела вообще нет. Некоторые рейкасты также проходят.

Как ни странно, один тип тел, которые у меня есть (собственный враг), каким-то образом обнаруживает тело и сталкивается с ним. Рейкасты, которые делают попытки врагов, работают — когда ваш персонаж прячется за полигоном, они как будто его не видят.

Другая странная вещь: когда я пробую тот же код, только использую SetAsBox вместо SetAsArray, он работает именно так, как должен.

Я использую собственный класс ContactListener, но я не выполнял никакой фильтрации контактов (если только это невозможно сделать, не осознавая этого).

Я использую версию Box2D 2.1a для Flash 9.

Какие-либо предложения? Я упускаю что-то очевидное или я (не дай Бог!) обнаружил ошибку? Спасибо за вашу помощь!

Андрей


person Andrey    schedule 14.04.2011    source источник


Ответы (2)


Привет Андрей,

2.1a более строгий, поэтому вам нужно объявить почти все, чтобы он работал правильно.

АС3 ООП-

private var body:b2Body;
private var bodyDef:b2BodyDef = new b2BodyDef();
private var bodyPoly:b2PolygonShape = new b2PolygonShape();
private var bodyFix:b2FixtureDef = new b2FixtureDef();

private var vertexArray:Array = new Array();

public function Example() 
{

//Setting up Vertices in an Array   
var ver1:b2Vec2 = new b2Vec2( -1, -1);
var ver2:b2Vec2 = new b2Vec2( 1, -1);
var ver3:b2Vec2 = new b2Vec2( 1, 1);
var ver4:b2Vec2 = new b2Vec2( -1, 1);

//Push in order
vertexArray.push(ver1, ver2, ver3, ver4);

bodyDef.type = b2Body.b2_dynamicBody;
//b2Vec2 Array then Vertex Count
bodyPoly.SetAsArray(vertexArray, vertexArray.length);
bodyFix.shape = bodyPoly;
bodyFix.density = 0.5;
bodyFix.friction = 0.5;
bodyFix.restitution = 0.5;
bodyDef.position.Set(0, 0);
body = m_world.CreateBody(bodyDef);
body.CreateFixture(bodyFix);

}

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

var ver1:b2Vec2 = new b2Vec2( -1, -1);//Top Left
var ver2:b2Vec2 = new b2Vec2( 1, -1);//Top Right
var ver3:b2Vec2 = new b2Vec2( 1, 1);//Bottom Right
var ver4:b2Vec2 = new b2Vec2( -1, 1);//Bottom Left

Размещение слева направо

vertexArray.push(ver1, ver2, ver3, ver4);

Я не очень хорошо объясняю вещи, но я надеюсь, что это поможет! -Нуль

person b2Zero    schedule 15.04.2011
comment
Привет, Зеро, сегодня я обнаружил, в чем проблема, но не смог опубликовать сообщение из-за 24-часового ожидания. В любом случае, ты довольно сильно прибил его. Оказывается, моя проблема заключалась в перечислении вершин в порядке против часовой стрелки. Я попытался ввести их по часовой стрелке, и это сработало! Во всех руководствах говорится, что это CCW, но они также говорят: CCW относится к правосторонней системе координат с осью z, указывающей из плоскости. Это может оказаться по часовой стрелке на вашем экране, в зависимости от вашей системы координат. Кто-нибудь может это объяснить? -Андрей - person Andrey; 15.04.2011

Привет еще раз, поскольку большинство версий Box2D были написаны разными людьми, исходный код изменился вместе с ним, чтобы лучше соответствовать языку программирования, документация, которую вы просматривали, вероятно, относилась к другому языку, а не к AS3, скорее всего C++.

В вашем исходном коде должна быть папка с документацией для этой версии, это должна быть папка с именем «Документы».

person b2Zero    schedule 15.04.2011
comment
Только что проверил руководства по C++ и AS3 в Интернете и в загруженной библиотеке, которую я использую. Я видел некоторые неточности в онлайн-версии AS3, я думаю, но C++ довольно современен. Думаю, я попробую спросить на форумах Box2D, они бы знали. Спасибо за вашу помощь! -Андрей - person Andrey; 15.04.2011