【发布时间】:2013-12-12 04:01:32
【问题描述】:
好的,我有一个平铺地图(显然)并实现了一个碰撞检测系统,它对我来说非常有效。不过,那些讨厌的角落有问题。我知道为什么会这样,因为我什至不检查角落。这就是重点,我不知道该怎么做。所以,首先这里是我当前的代码:
Body body = currentObject.Body; // Body is a class storing position, velocity, bounds and so on.
int tileDimensions = level.TileWidth; // Since the tiles are squares...
int leftTile = body.Bounds.Left / tileDimensions;
int topTile = body.Bounds.Top / tileDimensions;
int rightTile = (int)Math.Ceiling((float)body.Bounds.Right / tileDimensions - 1);
int bottomTile = (int)Math.Ceiling(((float)body.Bounds.Bottom / tileDimensions) - 1);
if (body.Velocity.Y > 0) // Moving down.
{
for (int x = leftTile; x <= rightTile; x++)
{
for (int y = bottomTile + 1; y <= (bottomTile + 1) + (body.Velocity.Y / tileDimensions); y++)
{
if (tiles[x, y] != null && !tiles[x, y].IsPassable)
{
newVelocity = new Vector2(body.Velocity.X, MathHelper.Clamp(body.Velocity.Y, 0, tiles[x, y].Body.Bounds.Top - body.Bounds.Bottom));
body.Velocity = newVelocity;
break;
}
}
}
}
所以这只是为了向下移动。对于上、左和右,还有其他 3 个类似的结构。唯一真正的区别是循环和我钳制速度的方式。
如您所见,我只是循环遍历所有可能发生碰撞的图块。然后我钳制速度,这会减慢速度,以防万一确实有一块瓷砖挡住了它。
现在,恐怕很难用文字来解释我的问题,所以我也得发一张照片。
在此屏幕截图中,黄色表示无法通过的瓷砖,黑色是上述代码当前正在检查碰撞的瓷砖,红色是玩家。
为了向您展示问题所在,想象一下我要在这个框架内加速。如您所见,我的播放器右上角的图块会发生碰撞,但玩家只会移动到图块中,因为我没有检查它是否有碰撞。而且我也不会在下一帧中检查它,因为我不检查我所在的块,因为......我什至不知道,这会背叛我的代码背后的整个想法,不是吗? :P
当然,我可以扩大我的“搜索”范围,但是我会与瓷砖发生碰撞,我不应该与之发生碰撞。 目前,我正在通过对我的边界重叠的所有图块进行额外检查来解决此问题,并且......你知道,如果我发现任何东西,只需将播放器移回即可。但这真的很混乱,并且不能保持初始速度。如果玩家撞到一个角落,他会移动到角落里,我会检测到,将他移回并归零他的速度。就是感觉不对,太笨重了。
我似乎想不出处理这种情况的好方法。我不会经常发生(因为它真的很难复制)但偶尔会发生,这当然是不可接受的。
我真的很想没有一个错误修复类型的东西,而是尽可能好地将它集成到我的其他代码中。这不是强制性的,但能够做到这一点会很酷。 所以如果你们中的任何人可以向我扔东西,我真的很感激。
无论如何,我希望你能听懂我想说的话。由于英语不是我的母语,因此有时很难解释这些事情。而且我真的不擅长解释事情:/
【问题讨论】:
-
解释有点冗长,但你的英文不错:)
-
这就是我添加第二个借口的原因:P。还有在线翻译,这会有所帮助;)
标签: c# xna collision-detection