0

我知道有 C# 或 XNA 的物理插件,但我想创建自己的,所以我可以了解这个主题。

我的问题如下:

我尝试以正确的角度和速度对我的角色施加弹性脉冲。速度以正确的方式计算,角度不正确并且扭曲了结果!下一个问题是,我的角色进入了颤抖模式,尽管它应该静止不动。我知道问题出在哪里,但我不知道如何解决(编辑:我是否必须为此考虑穿透深度?)

IPhysicsObject继承了最重要的信息,在Vector2[]索引 0 处具有碰撞点,在索引 1 处具有穿透深度。

我试过用这个但是是的..我不知道

    public void ElasticImpulse(IPhysicsObject Object, Vector2[] _colPos)
    {
        //this function is down below
        if (checkCollidingObjects(m_cCharacter, Object))
            return;

        //this List is like this declined:
        //public static List<IPhysicsObject[]> CollidingObjects = new List<IPhysicsObject[]>();
        //this list contains every pair of objects, that collided this frame, it is cleared after all physics and game logic is done.
        CollidingObjects.Add(new IPhysicsObject[] { m_cCharacter, Object });

        //deltavelocity is the velocity between two frames
        Vector2 v1 = Velocity - DeltaVelocity;
        float lv1 = (float)Math.Sqrt(v1.X * v1.X + v1.Y * v1.Y);
        float m1 = Mass;
        float k1 = Damping;

        Vector2 v2 = Object.Physik.Velocity - Object.Physik.DeltaVelocity;
        float lv2 = (float)Math.Sqrt(v2.X * v2.X + v2.Y * v2.Y);
        float m2 = Object.Mass;
        float k2 = Object.Physik.Damping;

        Vector2 colDir1 = _colPos[0] - m_cCharacter.Position;
        Vector2 colDir2 = _colPos[0] - Object.Position;
        colDir1.Normalize();
        colDir2.Normalize();
        Vector2 colNorm1 = new Vector2(colDir1.Y, -colDir1.X);
        Vector2 colNorm2 = new Vector2(colDir2.Y, -colDir2.X);
        float ldir1 = (float)Math.Sqrt(colNorm1.X * colNorm1.X + colNorm1.Y * colNorm1.Y);
        float ldir2 = (float)Math.Sqrt(colNorm2.X * colNorm2.X + colNorm2.Y * colNorm2.Y);

        float pi = MathHelper.Pi;
        //float angle1 = pi - ((v1.X * colNorm1.X + v2.Y * colNorm1.Y) / (lv1 * ldir1)) / v1.Length();
        float angle1 = pi - (float)Math.Acos(((v1.X * colNorm1.X + v2.Y * colNorm1.Y) / (lv1 * ldir1)) / v1.Length());
        angle1 = (float.IsNaN(angle1)) ? 0 : angle1;
        //float angle2 = pi - ((v2.X * colNorm2.X + v2.Y * colNorm2.Y) / (lv2 * ldir1)) / v2.Length();
        float angle2 = pi - (float)Math.Acos(((v2.X * colNorm2.X + v2.Y * colNorm2.Y) / (lv2 * ldir1)) / v2.Length());
        angle2 = (float.IsNaN(angle2)) ? 0 : angle2;

        //calculating the new velocities u 1/2. Got this formula out of the wiki link i posted above (took the german wiki version)
        Vector2 u1 = (m1 * v1 + m2 * v2 - (m2 * (v1 - v2) * k2)) / (m1 + m2) - v1;
        Vector2 u2 = (m1 * v1 + m2 * v2 - (m1 * (v2 - v1) * k1)) / (m1 + m2) - v2;

        //transform the new velocities by the correct angle
        Vector2 newV1 = new Vector2(
            u1.X * (float)Math.Cos(angle1) - u1.Y * (float)Math.Sin(angle1),
            u1.X * (float)Math.Sin(angle1) + u1.Y * (float)Math.Cos(angle1));
        Vector2 newV2 = new Vector2(
            u2.X * (float)Math.Cos(angle2) - u2.Y * (float)Math.Sin(angle2),
            u2.X * (float)Math.Sin(angle2) + u2.Y * (float)Math.Cos(angle2));

        newV1 = new Vector2(
            (float.IsNaN(newV1.X)) ? 0 : newV1.X,
            (float.IsNaN(newV1.Y)) ? 0 : newV1.Y);
        newV2 = new Vector2(
            (float.IsNaN(newV2.X)) ? 0 : newV2.X,
            (float.IsNaN(newV2.Y)) ? 0 : newV2.Y);
        AddForce(newV1);
        Object.Physik.AddForce(newV2);
    }

    bool checkCollidingObjects(IPhysicsObject obj1, IPhysicsObject obj2)
    {
        if (CollidingObjects.Count > 0)
        {
            int a = CollidingObjects.FindIndex(x => (x[0] == obj1 && x[1] == obj2) || 
                                                    (x[1] == obj1 && x[0] == obj2));
            return a != -1;
        }
        return false;
    }
4

0 回答 0