自上而下飞船,计算运动

时间:2013-11-22 12:56:16

标签: java box2d libgdx game-physics

我正在研究什么是我的主要项目,它是一个自上而下的2d太空射击游戏。我正在使用Box2D动态主体和Libgdx库。

在我释放数学技能之前,这似乎是一个好主意!

我对机芯有问题,基本上我想要的是W加速,A和D旋转,S减速或制动,如果这是空间思考。

现在第一个障碍是试图通过按W来让船朝着它面向的方向移动,成功!现在无论你面对什么样的方式,W都会让你朝着这个方向前进。

现在出现了问题,我按下W并且我的船开始通过施加冲动加速,好,现在当我按下A或D旋转身体并在握住W时改变角度时,它只是继续向那个方向飞行除非我释放W并压制。现在这确实改变了方向但是我必须坐下来等待,这取决于冲击速度以抵消当前速度并实际开始直接加速。

我真正希望它做的是用W加速,任何时候我按A和D,它应该计算新的标题并开始去那里,但我似乎无法搞清楚。这是我的代码:

输入处理器(播放器):

public void update(float delta) {
    currentShip.shipAngle = currentShip.getBody().getAngle();

    // move the ship
    currentShip.getBody().applyForceToCenter(currentShip.getVelocity(), true);

    // Turn the ship
    currentShip.getBody().applyTorque(currentShip.steeringTorque, true);

}

@Override
public boolean keyDown(int keycode) {

    switch (keycode) {
    case Keys.D:
        if (currentShip.getEngine() != null) {
            currentShip.steeringTorque = -1f;
            break;
        } else {
            System.out.println("No engine fitted!");
            break;
        }
    case Keys.A:
        if (currentShip.getEngine() != null) {
            currentShip.steeringTorque = 1f;
            break;
        } else {
            System.out.println("No engine fitted!");
            break;
        }
    case Keys.W:
        if (currentShip.getEngine() != null) {
            currentShip.velocity.x = MathUtils
                    .cos(currentShip.shipAngle)
                    * currentShip.getEngine().getAccelleration().x;
            currentShip.velocity.y = MathUtils
                    .sin(currentShip.shipAngle)
                    * currentShip.getEngine().getAccelleration().x;

            break;
        } else {
            System.out.println("No engine fitted!");
            break;
        }
    case Keys.S:
        if (currentShip.getEngine() != null) {
            break;
        } else {
            System.out.println("No engine fitted!");
            break;
        }
    case Keys.B:
        currentShip.shipAngle = 0;
        currentShip.getBody().setLinearVelocity(0, 0);
        break;
    case Keys.SPACE:
            if (currentShip.getEngine() != null) {
            System.out.println("Already have an engine fitted!");
            break;
        } else {
            Ship.addModule(new Engine(new Vector2(10, 10f), 10));
            System.out.println("Engine fitted!");
            break;
        }
    }

    return false;
}

我不认为这是相关的,但这是引擎类:

public class Engine extends Module{

public Vector2 accelleration = new Vector2();
public Vector2 decelleration = new Vector2();
public float maxSpeed;

/**
 * 
 * @param accelleration - The max accelleration this engine can supply
 * @param maxSpeed - The max terminal velocity that this engine can have
 */
public Engine(Vector2 accelleration, float maxSpeed){
    this.accelleration = accelleration;
    this.maxSpeed = maxSpeed;
}

public Vector2 getAccelleration() {
    return accelleration;
}

public void setAccelleration(Vector2 accelleration) {
    this.accelleration = accelleration;
}

public void setMaxSpeed(float maxSpeed) {
    this.maxSpeed = maxSpeed;
}

}

这是我的船的Box2D属性:

    this.width = 70;
    this.height = 30;

    // Setup ships model
    bodyDef.type = BodyType.DynamicBody;
    bodyDef.position.set(position);

    body = world.createBody(bodyDef);

    chassis.setAsBox(width / GameScreen.WORLD_TO_BOX_WIDTH, height / GameScreen.WORLD_TO_BOX_HEIGHT);
    fixtureDef.shape = chassis;
    fixtureDef.friction = 0.225f;
    fixtureDef.density = 0.85f;

    fixture = body.createFixture(fixtureDef);
    sprite = new Sprite(new Texture(Gdx.files.internal("img/TestShip.png")));
    body.setUserData(sprite);

    chassis.dispose();

tl; dr我按A或D时需要计算新角度,然后在不释放W键的情况下改变船舶移动的方向。

1 个答案:

答案 0 :(得分:2)

当您按下A / W键时,您将直接设置身体的速度。我认为你应该向它施加力量,使它朝着你想要的方向前进。这是一个物理模拟,如果你想将它限制在你的身体可以行进的最大速度,你应该只是直接设置速度。或者当你希望身体只沿某个方向移动时(例如导弹)重新分配速度(速度)。

我也玩二维空间模拟。其中一个,我正在创造一个朝着用户想要的方向移动的导弹。在这种情况下,他们通过将手指放在屏幕上来做这件事(这是一款iPad游戏)。

至少有两种方法可以做到这一点。

  1. 当您想要加速并转动身体(如导弹)时,向后施加推力。
  2. 按照自己的意愿转动身体,并沿一个方向施加推力,使身体朝着你想要的方向移动。
  3. 他们的行动和工作方式都有权衡。最大的折衷是当你从一个地方移动到另一个地方时,在(1)中,你将永远向前移动,这看起来正如人们在想到太空船(向前移动)时所想到的那样。您也可以尝试将其用于车辆控制,但是您必须取消侧面作用力(我做过)或者运动有点时髦且难以控制。

    在(2)中,身体转向面向它朝向的方向,这更像是我感觉人们朝着某个位置移动的方式。此外,(2)允许你在拍摄时让身体向后移动等。所以它对角色控制器更有用。

    在这两种情况下,我发现这样做的简单方法是有一个“点”,你希望角色向前移动,并将扭矩和推力施加到身体上以使其朝向该点移动。我有两种不同类型的字符(c ++类),一种像(1)一样移动,另一种像(2)一样移动。

    我在post中给出了(2)的部分答案 有一个完整的代码库(C ++)和位于here的演示视频。它位于Cocos2d-x中,但代码评论很好,网站上有帖子显示类的结构等。

    这有用吗?