如何向身体的行进方向施加力(Box2D)?

rph*_*101 5 android box2d andengine

我正在使用AndEngine/Box2d来开发游戏.我有一个球在屏幕上反弹.我已经成功地通过施加相反的力来忽略重力,但是在初始冲动之后它有一个减速的速度,即使弹性设置为1.基本上我想:

if(speed < a number)在运动方向上施加力或冲动(哪个更好?)

我怎么能这样做?

rph*_*101 6

不幸的是,球与其他物体相互作用,因此设定速度不起作用,但我找到了解决方案!

使用力量和相当广泛的触发,我终于提出:

private static class Ball extends Sprite  {
    Body body;

    public Ball(final float pX, final float pY, final ITextureRegion pTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager) {
        super(pX, pY, pTextureRegion, pVertexBufferObjectManager);
        body = PhysicsFactory.createCircleBody(mPhysicsWorld, this, BodyType.DynamicBody, PhysicsFactory.createFixtureDef(0, 1, 0));
        body.applyLinearImpulse(((float)5),(float) 5, body.getWorldCenter().x,  body.getWorldCenter().y);
        mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(this, body, true, true));
        scene.attachChild(this);
    }

    @Override
    protected void onManagedUpdate(final float pSecondsElapsed) {       
        body.applyForce(new Vector2(0,-SensorManager.GRAVITY_EARTH), new Vector2(body.getWorldCenter()));

        float vx = body.getLinearVelocity().x, vy = body.getLinearVelocity().y, vr=(float) Math.sqrt(vx*vx+vy*vy);
        float t= (float) Math.atan(Math.abs(vy/vx));
        if(vr<destroyerVelocity){
            if(vx>0&&vy<0)
                body.applyForce((float) ((destroyerVelocity-vr)*Math.cos(t)*body.getMass()), (float) (-(destroyerVelocity-vr)*Math.sin(t)*body.getMass()), body.getWorldCenter().x,  body.getWorldCenter().y);
            else if(vx>0&&vy>0)
                body.applyForce((float) ((destroyerVelocity-vr)*Math.cos(t)*body.getMass()), (float) ((destroyerVelocity-vr)*Math.sin(t)*body.getMass()), body.getWorldCenter().x,  body.getWorldCenter().y);
            else if(vx<0&&vy>0)
                body.applyForce((float) (-(destroyerVelocity-vr)*Math.cos(t)*body.getMass()), (float) ((destroyerVelocity-vr)*Math.sin(t)*body.getMass()), body.getWorldCenter().x,  body.getWorldCenter().y);
            else if(vx<0&&vy<0)
                body.applyForce((float) (-(destroyerVelocity-vr)*Math.cos(t)*body.getMass()), (float) (-(destroyerVelocity-vr)*Math.sin(t)*body.getMass()), body.getWorldCenter().x,  body.getWorldCenter().y);
        }
        if(vr>destroyerVelocity){
            if(vx>0&&vy<0)
                body.applyForce((float) (-(vr-destroyerVelocity)*Math.cos(t)*body.getMass()), (float) ((vr-destroyerVelocity)*Math.sin(t)*body.getMass()), body.getWorldCenter().x,  body.getWorldCenter().y);
            else if(vx>0&&vy>0)
                body.applyForce((float) (-(vr-destroyerVelocity)*Math.cos(t)*body.getMass()), (float) (-(vr-destroyerVelocity)*Math.sin(t)*body.getMass()), body.getWorldCenter().x,  body.getWorldCenter().y);
            else if(vx<0&&vy>0)
                body.applyForce((float) ((vr-destroyerVelocity)*Math.cos(t)*body.getMass()), (float) (-(vr-destroyerVelocity)*Math.sin(t)*body.getMass()), body.getWorldCenter().x,  body.getWorldCenter().y);
            else if(vx<0&&vy<0)
                body.applyForce((float) ((vr-destroyerVelocity)*Math.cos(t)*body.getMass()), (float) ((vr-destroyerVelocity)*Math.sin(t)*body.getMass()), body.getWorldCenter().x,  body.getWorldCenter().y);
        }
        super.onManagedUpdate(pSecondsElapsed);
    }
}
Run Code Online (Sandbox Code Playgroud)

基本上它的作用是创造一个身体并对它施加冲动以使其移动(由于某种原因,它比力更好).在每次更新时,施加与重力相反的力,以使球保持高空(基本上是漂浮的).弹性设定为1,因此碰撞几乎是完全弹性的.现在是棘手的部分:我计算了x和y的速度(分别为vx和vy),并用这些来计算合成速度(vr)和它们在(t)中行进的角度.

如果vr小于我想要的速度(destroyerVelocity),则施加一个力将其撞回到驱逐舰速度.由于F = mv/t且我只使用t = 1,因此在一个方向上施加的力等于所需速度 - 实际速度*x/y(即cos/sin)*物体的质量.如果物体在正x方向和负y方向上行进,则施加(x,-y)的力,等等.

为了使速度尽可能接近驱逐舰速度,如果碰巧大于驱逐舰速度,我必须在相反方向施加一个力.这是以相同的方式完成的,只是用相反的力量.

运行合成速度的日志语句(destroyerVelocity为7),其内容如下:6.900001,6.9995001,7.00028,7.13005,......

虽然球有时会飙升到15或20,但通常只需要2到3圈就可以达到+ - .5的7,这对我来说已经足够了!希望这有助于其他人寻找同样的事情.