2D 矩形碰撞检测系统(在真实游戏中工作)
在过去的几个月里,我一直在利用业余时间开发一款游戏。我一遍又一遍地重新实现但没有得到 100% 工作的一个症结是碰撞检测。我的系统(下面发布)大部分都可以工作,但是随机的事情似乎时不时地发生,比如玩家被推到关卡范围之外等。我遇到的关于这个问题的教程似乎提供了基本的工作原理,即,你有知道一个对象与相关对象的关系,但在真正的游戏中你不会真正知道这一点。这是我的实现,但我所追求的是是否有人知道一个良好可靠的系统来实现我在这里所做的事情。
请注意,该 item 来自 IItem 的集合,它公开了每个项目的 Rectangle 和其他一些位。
public void Move(float xAdditional, float yAdditional)
{
X += xAdditional;
Y += yAdditional;
foreach (var item in Level.Items)
{
if (item != this)
{
if (item.Boundary.Intersects(this.Boundary))
{
if (item.Boundary.Top > this.Boundary.Top) //we have collided with an object below us.
{
Y = item.Boundary.Top - (this.Boundary.Height/2);
}
if(item.Boundary.Bottom < this.Boundary.Bottom)//we have collided with an object above us.
{
Y = item.Boundary.Bottom + (this.Boundary.Height/2);
}
if(item.Boundary.Left > this.Boundary.Left) //We have collided with an object to the right.
{
X = item.Boundary.Left - (this.Boundary.Width/2);
}
if(item.Boundary.Right < this.Boundary.Right)// We have collided with an object to the left;
{
X = item.Boundary.Right + (this.Boundary.Width/2);
}
}
}
}
}
I have been developing a game in my spare time for the past few months. One sticking point that I have reimplemented over and over and not got 100% working is the collision detection. My system (posted below) mostly works however random things seem to happen from time to time, like the player being pushed outside the bounds of the level etc. Tutorials on the matter I have come across seem to offer basic workings, i.e, you have to know an object will be in relation to the object in question, but in a real game you wouldn't really know this. Here is my implementation but what I am after is if anyone knows of a good solid system for achieving what I am doing here.
Note that item comes from a collection of IItem which exposes the Rectangle and a few other bits for each item.
public void Move(float xAdditional, float yAdditional)
{
X += xAdditional;
Y += yAdditional;
foreach (var item in Level.Items)
{
if (item != this)
{
if (item.Boundary.Intersects(this.Boundary))
{
if (item.Boundary.Top > this.Boundary.Top) //we have collided with an object below us.
{
Y = item.Boundary.Top - (this.Boundary.Height/2);
}
if(item.Boundary.Bottom < this.Boundary.Bottom)//we have collided with an object above us.
{
Y = item.Boundary.Bottom + (this.Boundary.Height/2);
}
if(item.Boundary.Left > this.Boundary.Left) //We have collided with an object to the right.
{
X = item.Boundary.Left - (this.Boundary.Width/2);
}
if(item.Boundary.Right < this.Boundary.Right)// We have collided with an object to the left;
{
X = item.Boundary.Right + (this.Boundary.Width/2);
}
}
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
最终的解决方案是放弃我自己的解决方案并实施 Farseer。
谢谢
经过一段时间的使用,我选择了Physics2d.net,从开发人员的角度来看,我发现它更有用。
The final solution was to drop my own solution and implement Farseer.
Thanks
After some time with it I then opted for physics2d.net which I have found much more usable from a developers point of view.
首先,碰撞检测在很大程度上取决于物体的几何形状。
有多种经过验证的可行解决方案融入线性代数数学中,
但它们取决于您尝试使用的几何形状。而不是
使用对象的属性实现算法尝试直接实现数学方程,然后使用结果来确定碰撞是否发生。 (就像使用向量 t = ab 一样,如果 |t|>0 碰撞,否则不会)。
如果你有一个简单的几何形状,比如矩形或圆形,你应该采取
研究“3D 游戏编程和数学”埃里克的计算机图形学
伦耶尔。
另请记住,您可以使用其他方法实现碰撞检测
就像精灵碰撞一样。另一种可能性是使用更高级别的框架
为您做这项工作(例如 OSG)
First of all, Collision Detection depends heavily on the object geometry.
There are multiple proven to work solutions cast into linear algebra math,
but they are dependent on the geometries you try to use. Rather than
implementing an algorithm using your object's properties try to implement a mathematic equation directly and then use the result to determine if your collision happened or not. (like using vectors t = a-b, if |t|>0 collision, else not).
If you have a simple geometry like rectangles or circles you should take a
look into 'Mathematics for 3d game programming & computer graphics' by Eric
Lengyel.
Also keep in mind that you can achieve collision detection with other methods
like sprite collision. Another possibility is to use a higher level framework
doing this work for you (e.g. OSG)