【问题标题】:simulating projectile velocity模拟弹丸速度
【发布时间】:2020-09-01 20:27:16
【问题描述】:

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

我发现了一些看起来正确的方程式,但在实际实现方面,它们大多超出了我的想象。

有什么想法吗?

【问题讨论】:

    标签: c# .net xna monogame


    【解决方案1】:

    你首先为你的游戏对象创建一个界面,比如

    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;
    

    你的游戏类的Draw 方法会有类似

    protected override void Draw(GameTime gt)
    {
        spritebatch.Begin();
        foreach(var item in Components)item.Draw(spritebatch);
        spritebatch.End();
    }
    

    游戏类的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;
    
                }
            }
        }
    }
    

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

    我已经实现了 Rectangle 之间的碰撞,因为它易于处理。如果你需要圆之间的碰撞,我建议你阅读一下弹性碰撞及其所需的二维方程https://en.wikipedia.org/wiki/Elastic_collision

    【讨论】:

    • 我会在测试完后通知您
    • 如果弹丸足够快且帧率足够低。射弹将直接穿过物体而不会与它们发生碰撞。最好从射弹和无穷远处沿其速度方向绘制一条线(射线)。然后沿着这条线找到最近的交点,然后用它来决定它是否会与下一帧内的对象发生碰撞。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-31
    • 2016-03-17
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    相关资源
    最近更新 更多