JBox2D libGDX中自上而下的汽车移动问题

3

我正在尝试实现一个Java版本的基于Emanuele Feronato的“Two ways to make Box2D cars”的上向汽车游戏。我了解一些box2d的基础知识,并且大部分代码已经转换为Java,只有少数例外。

然而,当我运行程序时,我的汽车根本不动。

如果我将所有内容都设置为动态体,则除左前轮外的所有车轮都会开始前后移动,将汽车前后抛来抛去,但最终没有任何作用。前两个关节是旋转关节,每个关节都有电机,而后面的关节则是棱柱形的,所以请纠正我如果我错了,前两个应该是唯一“旋转”/移动的。我感觉自己做错了什么,但是无论我看哪里,都是在动作脚本中,所以我不确定出了什么问题。

我已经检查过,所有的轮子都在正确的位置,关节也放置在正确的轮子上。我已经检查了电机转速,它也在运行。我的“ldirection”和“rdirection”的x分量始终为0,因此它会减少横向速度,而y则始终是一个值。所以它应该向前移动,对吧?

左前轮与车身保持相同的距离,随着车身的升降保持不变。因此,左前轮似乎正常工作。我检查了所有的代码,确保右前轮与左轮相同。

启动汽车 Starting Car

当加速向前时,只有两个右轮和后左轮来回移动。 When accelerating forward only the Two right wheels and back left wheel move back and forth. enter image description here

当我开始转动两个前轮时,后面的两个轮子仍然与车辆保持一致,但开始以某种对角线方向移动。最终,当前轮转过大约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);

任何建议都将不胜感激!即使只是一个线索也会非常有帮助!谢谢!


这可能是太多的代码,任何人都无法浏览并可视化发生了什么。要不就截个屏或者录个视频什么的吧。顺便问一下,为什么一个自上而下的汽车里会有一个棱柱关节? - iforce2d
据我所知,box2D中的平移关节是指保持在所需物体的给定方向上并且只能滑动的关节,这就是为什么我继续使用平移关节来控制后两个轮子。我将上下平移量设置为0,这样它们就不应该能够垂直滑动,因此应该与车身保持平行。@iforce2d - BBogie
我怀疑你需要在这个问题中注入一些面向对象的设计。你应该有一个名为“Wheel”的对象,它具有可以设置的属性,使其表现得像左前轮、右前轮或后轮。让你的车轮和车身扩展或聚合box2d对象。如果不使用面向对象的方法,很快就会变得复杂和混乱。 - Scuba Steve
1个回答

0
try this code 


RaceCar::RaceCar( b2World* world )  
{       
b2Vec2 race_car_pos( 13.0f,
        13.0f );

/ Create race car chassis 
{       
    // Physics Body Shape           
b2Vec2 verticies[8];            
verticies[0].Set(  1.5f, 0.0f  );   
        verticies[1].Set(  3.0f, 2.5f  );   
        verticies[2].Set(  2.8f, 5.5f  );   
        verticies[3].Set(  1.0f, 10.0f ); 
            verticies[4].Set( -1.0f,
        10.0f );        
    verticies[5].Set( -2.8f, 5.5f  );   
        verticies[6].Set( -3.0f, 2.5f  );   
        verticies[7].Set( -1.5f, 0.0f  );

b2PolygonShape body_shape;      
    body_shape.Set( verticies, 8 );

// Physics body definition  
        b2BodyDef body_def;     
        body_def.type
        = b2_dynamicBody; 
//          body_def.position =b2Vec2(3,3);     
        // Physics Body Fixture             
b2FixtureDef body_fixture;      
    body_fixture.shape = &body_shape;           
body_fixture.density = 0.1f;

m_chassisPhysicsBody = world->CreateBody( &body_def );  
        m_chassisPhysicsBody->CreateFixture( &body_fixture );           m_chassisPhysicsBody->SetUserData( this );

m_chassisPhysicsBody->SetTransform( race_car_pos, 0.0f ); 
        }

// Tires 
{           b2Vec2 pos = m_chassisPhysicsBody->GetPosition();

// Top left tire    
        {
                        RCTire* tire_top_left = new RCTire( world );
                        tire_top_left->setPosition( race_car_pos );
                        m_tires.push_back( tire_top_left );

                        b2RevoluteJointDef joint_def;
                        joint_def.enableLimit = true;
                        joint_def.lowerAngle = 0.0f;
                        joint_def.upperAngle = 0.0f;
                        joint_def.bodyA = m_chassisPhysicsBody;
                        joint_def.localAnchorB.SetZero();
                        joint_def.bodyB = tire_top_left->getPhysicsBody();
                        joint_def.localAnchorA.Set( -3.0f, 8.5f );
                        b2RevoluteJoint* joint = static_cast<b2RevoluteJoint*>( world->CreateJoint( &joint_def ) );
                        tire_top_left->setJointToChassis( joint );          }

// Top right tire   
{
                        RCTire* tire_top_right = new RCTire( world );
                        tire_top_right->setPosition( race_car_pos );
                        m_tires.push_back( tire_top_right );

                        b2RevoluteJointDef joint_def;
                        joint_def.enableLimit = true;
                        joint_def.lowerAngle = 0.0f;
                        joint_def.upperAngle = 0.0f;
                        joint_def.bodyA = m_chassisPhysicsBody;
                        joint_def.localAnchorB.SetZero();
                        joint_def.bodyB = tire_top_right->getPhysicsBody();
                        joint_def.localAnchorA.Set( 3.0f, 8.5f );
                        b2RevoluteJoint* joint = static_cast<b2RevoluteJoint*>( world->CreateJoint( &joint_def ) );
                        tire_top_right->setJointToChassis( joint );             }

// Bottom left tire 
{
                        RCTire* tire_bottom_left = new RCTire( world );
                        tire_bottom_left->setPosition( race_car_pos );
                        m_tires.push_back( tire_bottom_left );

                        b2RevoluteJointDef joint_def;
                        joint_def.enableLimit = true;
                        joint_def.lowerAngle = 0.0f;
                        joint_def.upperAngle = 0.0f;
                        joint_def.bodyA = m_chassisPhysicsBody;
                        joint_def.localAnchorB.SetZero();
                        joint_def.bodyB = tire_bottom_left->getPhysicsBody();
                        joint_def.localAnchorA.Set( -3.0f, 0.5f );

                        b2RevoluteJoint* joint = static_cast<b2RevoluteJoint*>( world->CreateJoint( &joint_def ) );
                        tire_bottom_left->setJointToChassis( joint );           }

                    // Bottom right tire            {
                        RCTire* tire_bottom_right = new RCTire( world );
                        tire_bottom_right->setPosition( race_car_pos );
                        m_tires.push_back( tire_bottom_right );

                        b2RevoluteJointDef joint_def;
                        joint_def.enableLimit = true;
                        joint_def.lowerAngle = 0.0f;
                        joint_def.upperAngle = 0.0f;
                        joint_def.bodyA = m_chassisPhysicsBody;
                        joint_def.localAnchorB.SetZero();
                        joint_def.bodyB = tire_bottom_right->getPhysicsBody();
                        joint_def.localAnchorA.Set( 3.0f, 0.5f );
                        world->CreateJoint( &joint_def );
                        b2RevoluteJoint* joint = static_cast<b2RevoluteJoint*>( world->CreateJoint( &joint_def ) );
                        tire_bottom_right->setJointToChassis( joint );          }       }   }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接