【发布时间】:2020-09-01 20:27:16
【问题描述】:
我正在 Monogame/XNA 中制作一个自上而下的 2d 射击游戏,我想准确地模拟弹丸随时间的运动(每帧),并在它与另一个物体或其他物体碰撞时检测它的速度地面(给定弹丸的角度、初始速度、质量和阻力)。
我发现了一些看起来正确的方程式,但在实际实现方面,它们大多超出了我的想象。
有什么想法吗?
【问题讨论】:
我正在 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;
你的游戏类的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
【讨论】: