【发布时间】:2014-08-04 03:30:00
【问题描述】:
我正在尝试基于Emanuele Feronato's "Two ways to make Box2D cars" 实现自上而下的汽车 游戏的Java 版本。我知道box2d 的一些基础知识,并且在大多数情况下,我将代码转换为Java,几乎没有例外。
但是,当我运行该程序时,我的汽车没有任何移动。
如果我把所有的东西都变成一个动态的车身,那么所有的车轮(除了左前轮)都会开始前后移动,让汽车前后甩动,但最终却无处可去。前两个关节是旋转关节,每个关节都有电机,而后面是棱柱形,所以如果我错了,请纠正我,但前两个应该是唯一“旋转”/移动的关节。我觉得我在做一些非常错误的事情,但是我在任何地方都看到它总是在动作脚本中,所以我不能 100% 确定哪里出了问题。
我已经检查过了,所有的轮子都在正确的位置,并且接头也安装到了正确的轮子上。我检查了电机速度,它也在运行。我的“ldirection”和“rdirection”的x分量始终为0,因此它正在扼杀横向速度,而y始终是一个值。所以真的应该向前发展吧?
随着车身上下移动,左前轮始终与车身保持相同的距离。所以左前线似乎工作正常。我检查了所有代码以确保右前轮与左轮相同。
启动车
向前加速时,只有两个右轮和左后轮前后移动。
当我开始转动两个前轮时,后两个轮子仍然与汽车保持一条直线,但开始以某种对角线方式移动。最终,当前轮转动 90 度时,它们开始几乎旋转接头的中心。
初始化
this.world = new World(new Vector2(0, 0), false);
this.box2Drender = new Box2DDebugRenderer();
this.LeftPJointDef = new PrismaticJointDef();
this.RightPJointDef = new PrismaticJointDef();
this.RightJointDef = new RevoluteJointDef();
this.LeftJointDef = new RevoluteJointDef();
this.CarBody = new PolygonShape();
this.RightRWheelShape = new PolygonShape();
this.RightFWheelShape = new PolygonShape();
this.LeftRWheelShape = new PolygonShape();
this.LeftFWheelShape = new PolygonShape();
this.LeftRWheelDef = new BodyDef();
this.RightRWheelDef = new BodyDef();
this.RightFWheelDef = new BodyDef();
this.LeftFWheelDef = new BodyDef();
this.bodyD = new BodyDef();
this.CarFixDef = new FixtureDef();
this.x = x;
this.y = y;
this.Cpos = new Vector2(x,y);
this.RRW = new Vector2((this.x + (this.x * XPrc)), (this.y + (this.y * -YPrc)));
this.RLW = new Vector2((this.x + (this.x * -XPrc)), (this.y + (this.y * -YPrc)));
this.FRW = new Vector2((this.x + (this.x * XPrc)), (this.y + (this.y * YPrc)));
this.FLW = new Vector2((this.x + (this.x * -XPrc)), (this.y + (this.y * YPrc)));
this.WheelSizeX = this.width * 0.25f;
this.WheelSizeY = this.length * 0.30f;
//setting bodyDef damping
bodyD.linearDamping = 0.5f;
bodyD.angularDamping = 0.5f;
//Adding bodyDef to the world and setting type as Dynamic
body = world.createBody(bodyD);
body.setType(BodyDef.BodyType.DynamicBody);
//setting the body position in the world using the Vector given.
body.setTransform(this.Cpos, (float) ((Math.PI) / 2));
//Adding the calculated Position vecotrs of the wheel's to each wheel def.
RightFWheelDef.position.add(FRW);
LeftFWheelDef.position.add(FLW);
RightRWheelDef.position.add(RRW);
LeftRWheelDef.position.add(RLW);
//Adding the wheels to the world using the Wheel Defs.
RightFWheel = world.createBody(RightFWheelDef);
LeftFWheel = world.createBody(LeftFWheelDef);
RightRWheel = world.createBody(RightRWheelDef);
LeftRWheel = world.createBody(LeftRWheelDef);
RightFWheel.setType(BodyDef.BodyType.DynamicBody);
RightRWheel.setType(BodyDef.BodyType.DynamicBody);
LeftFWheel.setType(BodyDef.BodyType.DynamicBody);
LeftRWheel.setType(BodyDef.BodyType.DynamicBody);
//Setting the car(box) and wheel size
CarBody.setAsBox(this.length, this.width);
LeftFWheelShape.setAsBox(WheelSizeX, WheelSizeY);
LeftRWheelShape.setAsBox(WheelSizeX, WheelSizeY);
RightRWheelShape.setAsBox(WheelSizeX, WheelSizeY);
RightFWheelShape.setAsBox(WheelSizeX, WheelSizeY);
CarFixDef.shape = CarBody;
RightFWheel.createFixture(RightFWheelShape, 1);
RightRWheel.createFixture(RightRWheelShape, 1);
LeftFWheel.createFixture(LeftFWheelShape, 1);
LeftRWheel.createFixture(LeftRWheelShape, 1);
body.createFixture(CarFixDef);
LeftJointDef.enableMotor = true;
RightJointDef.enableMotor = true;
LeftJointDef.maxMotorTorque = 500;
RightJointDef.maxMotorTorque = 500;
//Setting Front Wheel joints in respects to the wheels and body
LeftJointDef.initialize(body, LeftFWheel, LeftFWheel.getWorldCenter());
RightJointDef.initialize(body, RightFWheel, RightFWheel.getWorldCenter());
this.LeftJoint = (RevoluteJoint) world.createJoint(LeftJointDef);
this.RightJoint = (RevoluteJoint) world.createJoint(RightJointDef);
LeftPJointDef.enableLimit = true;
RightPJointDef.enableLimit = true;
//Translation Limit
LeftPJointDef.lowerTranslation = 0;
LeftPJointDef.upperTranslation = 0;
RightPJointDef.lowerTranslation = 0;
RightPJointDef.upperTranslation = 0;
//Setting Rear wheel joints in respects to wheel and body
LeftPJointDef.initialize(body, LeftRWheel, LeftRWheel.getWorldCenter(), new Vector2(1, 0));
RightPJointDef.initialize(body, RightRWheel, RightRWheel.getWorldCenter(), new Vector2(1, 0));
//adding the P Joints to the world.
this.LeftPJoint = (PrismaticJoint) world.createJoint(LeftPJointDef);
this.RightPJoint = (PrismaticJoint) world.createJoint(RightPJointDef);
这是我的更新方法。
KillOrthoVelocity(LeftFWheel);
KillOrthoVelocity(RightFWheel);
KillOrthoVelocity(LeftRWheel);
KillOrthoVelocity(RightRWheel);
//Driving
float r1 = LeftFWheel.getTransform().getRotation();
Vector2 ldirection = new Vector2((float) -Math.sin(r1), (float) Math.cos(r1));
ldirection.scl(enginespeed);
float r2 = RightFWheel.getTransform().getRotation();
Vector2 rdirection = new Vector2((float) -Math.sin(r2), (float) Math.cos(r2));
rdirection.scl(enginespeed);
LeftFWheel.applyForce(ldirection, LeftFWheel.getPosition(), true);
RightFWheel.applyForce(rdirection, RightFWheel.getPosition(), true);
//Steering
float movespeed;
movespeed = steerAng - LeftJoint.getJointAngle();
LeftJoint.setMotorSpeed(movespeed * AngleSpeed);
movespeed = steerAng - RightJoint.getJointAngle();
RightJoint.setMotorSpeed(movespeed * AngleSpeed);
world.step(dt, 6, 2);
KillOrthoVelocity 类似于获取“ldirection”
Vector2 localP = new Vector2(0, 0);
Vector2 velocity = body.getLinearVelocityFromLocalPoint(localP);
float r = body.getTransform().getRotation();
Vector2 sideways = new Vector2((float) -Math.sin(r), (float) Math.cos(r));
sideways.scl(velocity.dot(sideways));
body.setLinearVelocity(sideways);
任何建议将不胜感激!即使只是一个线索也会非常有帮助! 谢谢!
【问题讨论】:
-
对于任何人来说,这可能是太多的代码,无法将正在发生的事情可视化。截图/视频之类的怎么样。顺便说一句,为什么自上而下的汽车会有一个棱柱接头?
-
据我所知,box2D(不算太多)棱柱关节是保持在给定方向上的关节,并且只能滑动,这就是我继续使用棱柱关节的原因后两个轮子。我将上下平移设置为 0,这样它们就不能垂直滑动,因此应该与身体保持平行。 @iforce2d
-
我怀疑您需要在这个问题中注入一点面向对象的设计。您应该有一个名为“Wheel”的对象,该对象具有您可以设置的属性,使其表现得像左前轮、右前轮或后轮。让您的车轮和车身扩展或聚合 box2d 对象。不使用面向对象的方法会很快变得复杂和混乱。
标签: java libgdx box2d game-physics jbox2d