android - 我如何在物体行进的方向上对物体施加力 (Box2D)?

标签 android box2d andengine

我正在使用 AndEngine/Box2d 开发游戏。我有一个在屏幕上弹跳的球。我已经通过施加相反的力成功地让它忽略了重力,但它有一个在初始脉冲后减速的租赁,即使弹性设置为 1。本质上我想:

如果(速度 <一个数字) 在运动方向上施加力或脉冲(哪个更好?)

我该怎么做?

最佳答案

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

利用力量和相当广泛的三角学,我终于想出了:

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);
    }
}

本质上,它所做的是创建一个物体并对其施加冲动以使其移动(出于某种原因,效果比力强得多)。在每次更新时,都会施加一个与重力相反的力,以保持球在空中(本质上是漂浮的)。弹性设置为 1,因此碰撞几乎是完全弹性的。现在是棘手的部分:我计算了 x 和 y 速度(分别为 vx 和 vy)并使用它们计算合成速度 (vr) 和它们在 (t) 中行进的角度。

如果 vr 小于我想要的速度 (destroyerVelocity),则会施加一个力将其恢复到驱逐舰速度。由于 F=mv/t 而我只使用 t=1,因此在一个方向上施加的力等于所需的速度 - 实际速度 * x/y(即 cos/sin)* 物体的质量。如果物体在正 x 方向和负 y 方向运动,则施加 (x,-y) 的力,依此类推。

为了使速度尽可能接近 destroyerVelocity,我必须在相反方向施加一个力,如果它恰好大于 destroyerVelocity。这是以相同的方式完成的,只是使用了相反的力。

运行合成速度的日志语句(驱逐舰速度为 7),它的内容如下:6.900001、6.9995001、7.00028、7.13005,...

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

关于android - 我如何在物体行进的方向上对物体施加力 (Box2D)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11257462/

相关文章:

java - android和引擎示例

Android RIL speech_codec_info

java - 在多项 Activity 中使用改造响应的最佳方式

java - 新的二进制 XML 文件行 #19 : Error inflating class activity

random - LibGDX 内部调用 MathUtils.random() 干扰生成的随机数序列

c++ - 更改对象的原点使其沿不同的轴移动

c++ Box2D在 vector 中移动和渲染动态物体

java - AndEngine GLES 2 - 黑屏,无错误

Java:在匿名操作处理程序中获取 "this"的正确上下文

android - 为什么有人想要绑定(bind)服务(而不创建它),而不是使用线程?