如何沿物体行进的方向(Box2D)向物体施加力? [英] How do I apply a force to a body in the direction it is traveling (Box2D)?

查看:36
本文介绍了如何沿物体行进的方向(Box2D)向物体施加力?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using AndEngine/Box2d to develop a game. I have a ball that bounces around the screen. I've successfully made it ignore gravity by applying an opposite force, but it has a tenancy to slow down after the initial impulse, even with the elasticity set to 1. Essentially I want to:

if(speed 一个数字)在运动方向施加力或脉冲(哪个更好?)

if(speed < a number) apply force or impulse (which is better?) in direction of motion

我该怎么做?

推荐答案

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

Well unfortunately, the ball is interacting with other objects so setting velocity did not work, but I have found a solution!

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

Using forces and fairly extensive trig, I finally came up with:

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).

Essentially what this does is create a body and apply an impulse to it to get it moving (worked a lot better than a force for some reason). On every update, a force is applied opposite that of gravity in order to keep the ball aloft (floating, essentially). The elasticity is set to 1, so collisions are almost perfectly elastic. And now the tricky part: I calculated the x and y velocities (vx and vy respectively) and used these to calculate the resultant velocity (vr) and the angle that they were traveling in (t).

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

If vr is less than the velocity I want (destroyerVelocity), then a force is applied to bump it back up to the destroyer velocity. Since F=mv/t and I just used t=1, the force applied in one direction is equal to the wanted velocity - the actual velocity * the x/y (that's the cos/sin) * the mass of the object. If the object is traveling in the positive x direction and negative y direction, then a force of (x,-y) is applied, and so on.

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

In order to keep the velocity as close to the destroyerVelocity as possible, I had to apply a force in the opposite direction if it happened to be greater than the destroyerVelocity. This was done in the same manner, just with an opposite force.

运行结果速度的日志语句(其中 destroyerVelocity 为 7),它会读取如下内容:6.900001, 6.9995001, 7.00028, 7.13005,...

Run a log statement of the resultant velocity (with the destroyerVelocity being 7) and it reads something like: 6.900001, 6.9995001, 7.00028, 7.13005,...

虽然球有时会尖刺到 15 或 20,但通常只需要 2 或 3 个循环即可使其在 7 的 +- .5 以内,这对我来说已经足够了!希望这可以帮助其他人寻找相同的东西.

Although the ball will spike to like 15 or 20 sometimes, it usually only takes 2 or 3 loops to get it within +- .5 of 7, which is good enough for me! Hope this helps anyone else looking for the same thing.

这篇关于如何沿物体行进的方向(Box2D)向物体施加力?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆