Java 自上而下的宇宙飞船,计算运动

Java 自上而下的宇宙飞船,计算运动,java,box2d,libgdx,game-physics,Java,Box2d,Libgdx,Game Physics,我正在进行我的主要项目,这是一个自上而下的2d太空射击。我使用的是Box2D动态实体和Libgdx库 这在当时似乎是个好主意,直到我发布了我的数学技能 我对运动有个问题,基本上我想要的是W加速,a和D旋转,S减速或刹车,如果这是在空间里思考的话 现在,第一个障碍是通过按W,成功,让飞船朝着它所面临的方向前进!不管你朝哪个方向走,W都会在这个方向上加速你 现在的问题是,我按下W,我的飞船开始加速,通过施加一个脉冲,很好,现在当我推动A或D旋转身体,改变角度,同时保持W,它只是继续朝那个方向飞行,除

我正在进行我的主要项目,这是一个自上而下的2d太空射击。我使用的是Box2D动态实体和Libgdx库

这在当时似乎是个好主意,直到我发布了我的数学技能

我对运动有个问题,基本上我想要的是W加速,a和D旋转,S减速或刹车,如果这是在空间里思考的话

现在,第一个障碍是通过按W,成功,让飞船朝着它所面临的方向前进!不管你朝哪个方向走,W都会在这个方向上加速你

现在的问题是,我按下W,我的飞船开始加速,通过施加一个脉冲,很好,现在当我推动A或D旋转身体,改变角度,同时保持W,它只是继续朝那个方向飞行,除非我释放W并抑制。现在这确实改变了方向,但我必须坐下来等待,这取决于脉冲的速度,以抵消当前的速度,并开始以正确的方向加速

我想要它做的是用W加速,只要我按下A和D,它就会计算出新的航向并开始向那里移动,但我似乎无法计算出来。这是我的密码:

输入处理器(播放器):

我认为这与此无关,但这是发动机等级:

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键的情况下改变船舶的移动方向。

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

我也经常玩二维空间模拟。在其中一个例子中,我创建了一个导弹,它朝着用户想要的方向移动。在这种情况下,他们将手指放在屏幕上(这是一款iPad游戏)

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

  • 当你想要加速和转动身体(像导弹一样)时,向后推
  • 如你所愿转动身体,并在一个方向上施加推力,迫使身体朝你所希望的方向移动
  • 两者在移动和工作方式上都有权衡。最大的权衡是当你从一个地方移动到另一个地方时,在(1)中,你总是会向前移动,这与人们在视觉上想到太空船(向前移动)时的想法是一致的。你也可以试着用它来控制车辆,但是你必须取消侧作用力(我做过),否则运动有点古怪,很难控制

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

    在这两种情况下,我发现最简单的方法是有一个“点”,你想让角色朝着这个点移动,并对身体施加转动扭矩和推力,使它朝着那个点移动。我有两种不同类型的字符(c++类),一种像(1)一样移动,另一种像(2)一样移动

    我在这篇文章中给出了(2)的部分答案。
    有一个完整的代码库(C++)和演示视频。它在Cocos2d-x中,但是代码有很好的注释,网站上也有显示类结构的帖子,等等


    这是否有用?

    与其将宇宙飞船的速度存储为x/y矢量,不如将其存储为方向和速度(即速度的大小);然后根据方向和速度计算每一步的速度。还要注意的是,宇宙飞船实际上不应该仅仅通过转动改变它的运动方向。。。动量守恒,基本上,我想得到物体的当前角度,并把它保存到一个叫做方向的区域,所以在我的例子中,它直接朝上(根据sysprint)90°,基本上是向北。然后我想做速度=方向,做数学,速度?也是的,但这不是一个公平的空间模拟器,所以欺骗一点是可以的,一些动力会被保留下来,所以飞船仍然有点滑翔/漂浮,这是基本的想法。尝试对x使用
    sin(方向)*速度
    ,对速度的y分量使用
    cos(方向)*速度
    。。。或者是另一种方式呢?我会两种都试试,现在不是在电脑前!迫不及待地想尝试一下:D将很快更新,结果与我的tbh相同,仍然按W,它会加速,我认为问题在于,当你按一个键时,它只会重复一次,直到你放开为止,它不会循环。假设我想增加速度,比如速度+=5,每次迭代增加施加的力5,不。按一次W,它就应用一次。它有助于扩展想法和方法,但我已经实现了一种类似于2的方法。这基本上是由于我处理输入的方式,按A或D时没有计算出船舶的新航向。非常好。我经常玩这种东西(我写小型太空射击游戏)。如果你想分享任何想法,请随时与我联系。
        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();