C# 模拟弹丸速度

C# 模拟弹丸速度,c#,.net,xna,monogame,C#,.net,Xna,Monogame,我正在用Monogame/XNA制作一个自上而下的2d射击游戏,我想精确地模拟一个投射物随时间的运动(每帧),并在它与另一个物体或地面碰撞时检测它的速度(给定投射物的角度、初始速度、质量和阻力) 我已经找到了一些看起来正确的方程,但它们在实际实现方面大多超出了我的理解 有什么想法吗?您可以先为游戏对象制作一个界面,例如 public abstract class PhyObj { Vector2 v;//Velocity Vector2 x;//Position floa

我正在用Monogame/XNA制作一个自上而下的2d射击游戏,我想精确地模拟一个投射物随时间的运动(每帧),并在它与另一个物体或地面碰撞时检测它的速度(给定投射物的角度、初始速度、质量和阻力)

我已经找到了一些看起来正确的方程,但它们在实际实现方面大多超出了我的理解


有什么想法吗?

您可以先为游戏对象制作一个界面,例如

public abstract class PhyObj
{
    Vector2 v;//Velocity
    Vector2 x;//Position
    float Mass; //If mass is going to be constant, you can make this readonly
    float Drag; //The Drag/friction
    Rectangle Dest;// The position of this Object in the game screen
    Texture2D texture;// The image/sprite for this object

    void Update(Vector2 acc)//acc is the acceleration inputted at a given time
    {
        a=a-(v*Drag); //Adjust actual acceleration with the drag involved
        v+=a;// dv/dt = a
        x+=v;// dx/dt = v

        //Adjust the position of the rectangle
        Dest.X=(int)x.X;
        Dest.Y=(int)x.Y;
    }
    void Draw(SpriteBatch s)
    {
        s.Draw(texture,Dest,Color.White);
    }
}
接下来,列出您将要维护的IPhyObj

LinkedList<IPhyObj> Components;
游戏类的
Update
方法与将要实现的碰撞检测和处理方法类似

protected override void Update(GameTime gt)
{
    //Update every object's position
    foreach(var item in Components)
    {
        Vector2 accinput=Vector2.Zero
        //Do something to compute the Acceleration vector
        item.Update(accinput);
    }


    //Collision management
    foreach(var item1 in Components)
    {
        foreach(var item2 in Components)
        {
            if(item1!=item2 && item1.Dest.Intersects(item2.Dest))//Collision deteted!
            {
                //Handle Collision. I am treating it as an elastic collision here

                var v1 = (((item1.Mass-item2.Mass)/(item1.Mass+item2.Mass))*item1.v) + (((2*item2.Mass)/(item1.Mass+item2.Mass))*item2.v);

                var v2 = v1 + item1.v - item2.v;

                item1.v= v1;
                item2.v= v2;

            }
        }
    }
}
这是一个非常基本的实现。我没有测试就输入了这个,所以让我知道它是否有效


我已经实现了矩形之间的碰撞,因为它很容易处理。如果你需要圆之间的碰撞,我建议你阅读一点关于弹性碰撞及其所需的2D方程的内容

我会在测试完后告诉你投射物是否足够快,帧率是否足够低。射弹将直接穿过物体而不会与它们碰撞。最好从射弹上画一条线(光线),沿着射弹的速度方向无限远。然后找到沿该线最近的交点,然后使用该交点确定它是否会在下一帧内与对象碰撞。
protected override void Update(GameTime gt)
{
    //Update every object's position
    foreach(var item in Components)
    {
        Vector2 accinput=Vector2.Zero
        //Do something to compute the Acceleration vector
        item.Update(accinput);
    }


    //Collision management
    foreach(var item1 in Components)
    {
        foreach(var item2 in Components)
        {
            if(item1!=item2 && item1.Dest.Intersects(item2.Dest))//Collision deteted!
            {
                //Handle Collision. I am treating it as an elastic collision here

                var v1 = (((item1.Mass-item2.Mass)/(item1.Mass+item2.Mass))*item1.v) + (((2*item2.Mass)/(item1.Mass+item2.Mass))*item2.v);

                var v2 = v1 + item1.v - item2.v;

                item1.v= v1;
                item2.v= v2;

            }
        }
    }
}