好的,我有一个平铺地图(显然)并实施了一个碰撞检测系统,对我来说非常好。虽然这些讨厌的角落有问题。我知道为什么会这样,因为我甚至不检查角落。这就是重点,我不知道该怎么做。所以,首先这是我目前的代码:
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
当然,我可以扩展我的“搜索”范围,但随后我会与瓷砖碰撞,我不应该碰撞。 目前,我正在通过对我的边界重叠的所有瓷砖进行额外检查来修复此问题,并且......如果我找到任何瓷砖,只需将播放器移回。但这真的很混乱,并没有保持初始速度。如果玩家击中一个角落,他将进入角落,我将检测到,将他移回并使他的速度无效。这感觉不对劲,很笨重。
我似乎无法找到处理此类案件的好方法。我并不经常发生(因为它很难复制)但偶尔会发生这种情况,这当然是不可接受的。
我真的很想甚至没有bugfix类型的东西,但要尽可能好地将它集成到我的其他代码中。这不是强制性的,但能够做到这一点很酷。 所以,如果你们中的任何人都能向我扔东西,我真的很感激。
无论如何,我希望你能够遵循我想说的话。由于英语不是我的母语,因此有时难以解释这些事情。我也很难解释一些事情:/
答案 0 :(得分:0)
我想你可以再添加4个案例,当currentObject在对角线上移动时处理,不是吗?
但是,您可能希望根据边界体积调查碰撞。