【问题标题】:Farseer: Object not bouncing back from static objectsFarseer:对象没有从静态对象反弹回来
【发布时间】:2014-08-26 05:33:14
【问题描述】:

我在四个静态矩形对象内有一个动态圆形对象。考虑一个盒子里面的球,静态矩形对象模拟盒子的墙壁。对于圆形对象,IgnoreGravity 设置为 true。我希望圆形物体撞击并从墙壁反弹回来。然而,当圆形物体与墙壁碰撞时,它会粘在墙壁上并沿着墙壁移动,而不是弹回。

以下是我正在使用的代码:

Body CircleBody;

const int CircleRadiusInPixels = 20;
const int CircleCentreXInPixels = 100;
const int CircleCentreYInPixels = 100;
Texture2D CircleTexture;

Body[] RectangleBody;
Texture2D RectangleTexture;

struct RectagleProperties
{
    public int WidthInPixels;
    public int HeightInPixels;
    public int CenterXPositionInPixels;
    public int CenterYPositionInPixels;

    public RectagleProperties(int Width, int Height, int X, int Y)
    {
        WidthInPixels = Width;
        HeightInPixels = Height;
        CenterXPositionInPixels = X;
        CenterYPositionInPixels = Y;
    }

};

RectagleProperties[] rectangleProperties;

World world;

const float PixelsPerMeter = 128.0f;
float GetMetres(int Pixels)
{
    return (float)(Pixels / PixelsPerMeter);
}

int GetPixels(float Metres)
{
    return (int)(Metres * PixelsPerMeter);
}



protected override void LoadContent()
{
    ...
    RectangleTexture = Content.Load<Texture2D>("Sprites/SquareBrick");
    CircleTexture = Content.Load<Texture2D>("Sprites/Circle");

    world = new World(new Vector2(0, 9.8f));

    CircleBody = BodyFactory.CreateCircle(world, GetMetres(CircleRadiusInPixels), 
                                          1, 
                                          new Vector2(
                                                GetMetres(CircleCentreXInPixels), 
                                                GetMetres(CircleCentreYInPixels)));
    CircleBody.BodyType = BodyType.Dynamic;
    CircleBody.IgnoreGravity = true;
    CircleBody.LinearVelocity = new Vector2(1, 1);

    rectangleProperties = new RectagleProperties[4];
    rectangleProperties[0] = new RectagleProperties(800, 20, 400, 10);
    rectangleProperties[1] = new RectagleProperties(800, 20, 400, 460);
    rectangleProperties[2] = new RectagleProperties(20, 480, 10, 240);
    rectangleProperties[3] = new RectagleProperties(20, 480, 790, 240);

    RectangleBody = new Body[4];
    for (int i = 0; i < rectangleProperties.Length; i++)
    {
        RectangleBody[i] = BodyFactory.CreateRectangle(world,
                                                       GetMetres(rectangleProperties[i].WidthInPixels),
                                                       GetMetres(rectangleProperties[i].HeightInPixels),
                                                       0.5f,
                                                       new Vector2(GetMetres(rectangleProperties[i].CenterXPositionInPixels),
                                                                   GetMetres(rectangleProperties[i].CenterYPositionInPixels)));
        RectangleBody[i].BodyType = BodyType.Static;

    }
    ....
}

经过一番挖掘,我发现VelocityConstraint 导致碰撞被视为非弹性。但是,如果我减小 VelocityConstraint 的值,则会导致奇怪的碰撞响应。

有人知道如何让球物体在与静态物体碰撞后反弹回来吗?

【问题讨论】:

    标签: c# xna farseer


    【解决方案1】:

    由于您尚未发布问题可能所在的更新方法的内容,因此我将做出一个合格的猜测。

    这似乎与一个很常见的问题有关:

    说圆形物体有一定的速度。 如果发生碰撞,您可以反转墙壁轴上的速度,并且速度会因重力或其他原因而降低一点。

    现在您应用新速度来解决碰撞问题,但由于速度降低,不足以解决碰撞问题,这意味着对象在下一次更新中仍会与墙壁发生碰撞。

    这将导致速度反复反转,因为对象永远不会获得足够的速度来再次脱离碰撞。

    对此的解决方案是在继续执行其他代码之前,最好在最短的轴上将对象移出碰撞(查看“分离轴定理”)。

    【讨论】:

    • 感谢您的回复。据我所知,我在 Update 方法中没有做任何特别的事情,除了更新 farseer 并从 farseer 获取对象的最新坐标。您所描述的内容是有道理的,但我期望 Farseer 引擎应该将球/圆移出碰撞对象的范围。我没有在碰撞处理程序中做任何事情。
    • 我想我忘记了这是在写这篇文章时与 Farseer 一起制作的。 Farseer 当然应该正确地做到这一点。但总得有个理由吧?我以前见过这种情况发生好几次。无论如何,我希望我的回答对你有所帮助。
    猜你喜欢
    • 1970-01-01
    • 2018-02-25
    • 2014-11-30
    • 2020-07-20
    • 1970-01-01
    • 2014-06-03
    • 2018-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多