Требуется связать два вагона как показано на рисунке:
Т.е. к вагонам крепится квадрат, который может вращаться (RevoluteJoint), а сами эти квадраты соединяются с помощью PrismaticJoint. Для PrismaticJoint мне удалось сделать ограничение, т.е. вагоны не подъезжают и не разъезжаются друг от друга, но нужно сделать еще ограничение вращения для RevoluteJoint, причем не упругое, а жесткое, чтобы за определенный угол (пусть будет от -10 до 10 градусов) квадраты не поворачивались не при каких условиях. Примерно вот что получилось у меня на данный момент:
function createVagon(num) {
const vagonWidth = 60/3;
const vagonHeight = 10/3;
const wheelSize = 20/3;
vagons[num] = {};
let fixDef = new box2d.b2FixtureDef();
fixDef.density = 5;
fixDef.friction = 10;
fixDef.restitution = 0;
let bodyDef = new box2d.b2BodyDef();
bodyDef.type = box2d.b2Body.b2_dynamicBody;
bodyDef.position.x = toMeters(500 - 200*num);
bodyDef.position.y = toMeters(400 - 10 - 20 - 50);
bodyDef.angle = 0;
vagons[num].body = world.CreateBody(bodyDef);
fixDef.shape = new box2d.b2PolygonShape();
fixDef.shape.SetAsBox(toMeters(vagonWidth), toMeters(vagonHeight));
vagons[num].body.CreateFixture(fixDef);
let wheel = world.CreateBody(bodyDef);
fixDef.shape = new box2d.b2CircleShape(toMeters(wheelSize));
wheel.CreateFixture(fixDef);
let joint = new box2d.b2Joints.b2RevoluteJointDef();
joint.bodyA = vagons[num].body;
joint.bodyB = wheel;
joint.localAnchorA = new box2d.b2Vec2(toMeters(vagonWidth-wheelSize/2), toMeters(vagonHeight+wheelSize/2));
joint.maxMotorTorque = 1.0;
// joint.motorSpeed = 30.0;
joint.enableMotor = true;
joint = world.CreateJoint(joint);
vagons[num].backWheel = joint;
wheel = world.CreateBody(bodyDef);
fixDef.shape = new box2d.b2CircleShape(toMeters(wheelSize));
wheel.CreateFixture(fixDef);
joint = new box2d.b2Joints.b2RevoluteJointDef();
joint.bodyA = vagons[num].body;
joint.bodyB = wheel;
joint.localAnchorA = new box2d.b2Vec2(-toMeters(vagonWidth-wheelSize/2), toMeters(vagonHeight+wheelSize/2));
joint.maxMotorTorque = 1;
joint.enableMotor = true;
joint = world.CreateJoint(joint);
vagons[num].frontWheel = joint;
bodyDef = new box2d.b2BodyDef();
bodyDef.type = box2d.b2Body.b2_dynamicBody;
let frontBind = world.CreateBody(bodyDef);
vagons[num].frontBind = frontBind;
fixDef.shape = new box2d.b2PolygonShape();
fixDef.shape.SetAsBox(toMeters(wheelSize/2), toMeters(wheelSize/2));
fixDef.filter.maskBits = 0x0000;
frontBind.CreateFixture(fixDef);
joint = new box2d.b2Joints.b2RevoluteJointDef();
joint.bodyA = vagons[num].body;
joint.bodyB = frontBind;
joint.lowerAngle = -10 * (Math.PI/180);
joint.upperAngle = 10 * (Math.PI/180);
joint.enableLimit = true;
joint.localAnchorA = new box2d.b2Vec2(toMeters(vagonWidth+wheelSize/2), toMeters(0));
joint = world.CreateJoint(joint);
let backBind = world.CreateBody(bodyDef);
vagons[num].backBind = backBind;
backBind.CreateFixture(fixDef);
joint = new box2d.b2Joints.b2RevoluteJointDef();
joint.bodyA = vagons[num].body;
joint.bodyB = backBind;
joint.lowerAngle = -10 * (Math.PI/180);
joint.upperAngle = 10 * (Math.PI/180);
joint.enableLimit = true;
joint.localAnchorA = new box2d.b2Vec2(-toMeters(vagonWidth+wheelSize/2), toMeters(0));
joint = world.CreateJoint(joint);
}
Но дело в том, что появилась некоторая упругость, но все равно вагоны имеют тенденцию крутиться друг вокруг друга при некоторых условиях, жестко ограничить угол не получилось. Вот код соединения вагонов между собой (если в нем дело):
let joint = new box2d.b2Joints.b2PrismaticJointDef();
joint.bodyA = vagons[1].frontBind;
joint.bodyB = vagons[0].backBind;
joint.lowerTranslation = toMeters(11.5);
joint.upperTranslation = toMeters(12);
joint.enableLimit = true;
joint.maxMotorForce = 1;
joint.motorSpeed = 0.0;
joint.enableMotor = true;
joint = world.CreateJoint(joint);
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости