【发布时间】:2017-04-19 03:18:00
【问题描述】:
所以我有一个Circle 结构,很简单,看起来像这样:
public struct Circle
{
public Circle(int x, int y, int radius) : this()
{
Center = new Point(x, y);
Radius = radius;
}
public Point Center { get; private set; }
public int Radius { get; private set; }
}
我有一个看起来像这样的PhysicsEnity 类:
public class PhysicsEntity
{
public int Width { get; protected set; }
public int Height { get; protected set; }
public Vector2 Position { get; set; }
public Vector2 Velocity { get; set; }
public float Restitution { get; protected set; }
public float Mass { get; protected set; }
public virtual void Update(GameTime gameTime)
{
float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
Velocity += ((Phys.Gravity * dt) * Mass);
Position += Velocity * dt;
}
public virtual void Draw(SpriteBatch spriteBatch) { }
public virtual void ApplyImpulse(Vector2 impulse)
{
Position += impulse;
}
}
我有两个继承自这个类的类。 CircleEntity 得到一个圆,RectangleEntity 得到一个矩形,但没有其他变化。
为了检查碰撞,我有一个辅助函数,它接收两个PhysicsEntity 对象,检查它们是什么类型(RectangleEntity 或CircleEntity),然后调用该特定碰撞类型的函数。如果发生碰撞,碰撞检测函数只会返回一个boolean。
然后我有一个名为ResolveCollision 的函数,它接受两个实体,如下所示:
public static void ResolveCollision(PhysicsEntity a, PhysicsEntity b)
{
if (a.Mass + b.Mass == 0)
{
a.Velocity = Vector2.Zero;
b.Velocity = Vector2.Zero;
return;
}
var invMassA = a.Mass > 0 ? 1 / a.Mass : 0;
var invMassB = b.Mass > 0 ? 1 / b.Mass : 0;
Vector2 rv = b.Velocity - a.Velocity;
Vector2 normal = Vector2.Normalize(b.Position - a.Position);
float velAlongNormal = Vector2.Dot(rv, normal);
if (velAlongNormal > 0) return;
float e = MathHelper.Min(a.Restitution, b.Restitution);
float j = (-(1 + e) * velAlongNormal) / (invMassA + invMassB);
Vector2 impulse = j * normal;
a.Velocity -= invMassA * impulse;
b.Velocity += invMassB * impulse;
}
Circle-Circle 碰撞和 Rectangle-Rectangle 碰撞可以正常工作,但 Circle-Rectangle 绝对不行。我什至无法让它正确检测碰撞,它总是返回错误。这是矩形-圆形碰撞检测:
public static bool RectangleCircleCollision(CircleEntity a, RectangleEntity b)
{
Circle c = a.Circle;
Rectangle r = b.Rectangle;
Vector2 v = new Vector2(MathHelper.Clamp(c.Center.X, r.Left, r.Right),
MathHelper.Clamp(c.Center.Y, r.Top, r.Bottom));
Vector2 direction = c.Center.ToVector2() - v;
float distSquare = direction.LengthSquared();
return ((distSquare > 0) && (distSquare < c.Radius * c.Radius));
}
此时我完全不知所措。我不知道出了什么问题。我已经研究了几乎所有的碰撞检测教程,我只是不知道。
我在这里做错了什么?
编辑:我弄错了,矩形矩形也不起作用。如果有人能指出我的 2D 碰撞检测白痴指南的方向,我将不胜感激。
【问题讨论】:
-
在这个主题上有很多很好的答案:stackoverflow.com/questions/401847/…
标签: c# xna collision-detection game-physics monogame