您的位置:首页 > 其它

XNA学习笔记——Tile Map的碰撞检测

2010-08-23 12:36 218 查看

如图所示,ABCD是四个相邻的tile,中间靠左深色矩形是角色矩形原先所处的位置,中间红色矩形是角色移动一定距离后所处的位置(先假设能够移动,相当于反证法),它的右上角和右下角分别是a点和b点,两个椭圆表示该tile中有障碍物存在。现在就讲一下大概的思路。

角色能不能移动,就看移动一定距离后,a点和b点所在的tile中有没有障碍物的存在,如果有,则不能移动。public bool CheckRight(Rectangle nextRectangle)
{
Point tile1 = VectorToCell(
new Vector2(nextRectangle.X, nextRectangle.Y));
Point tile2 = VectorToCell(
new Vector2(nextRectangle.X + nextRectangle.Width - 1,
nextRectangle.Y + nextRectangle.Height - 1));
bool doesCollide = false;
if (tile2.X >= mapWidth)
return !doesCollide;
int x = tile2.X;
for (int y = tile1.Y; y <= tile2.Y; y++)
{
if (GetCollisionValue(x, y) == CollisionType.Unpassable)
doesCollide = true;
}
return doesCollide;
}

Point tile1表示的是移动后的角色矩形的左上角所在的tile坐标(不是像素值);Point tile2表示的是移动后的角色矩形的右下角所在的tile坐标(不是像素值),其实离右下角还差一个像素,这样做的原因后面会叙述。之后的for循环就是检测B和D中有无障碍物。

假如角色矩形刚好处于A的位置,B中没有障碍物,D中有障碍物。如果不减去一个像素,那么角色矩形的右下角刚好是ABCD的中心,它的tile坐标会是D所在的tile坐标(通过VectorToCell方法计算)。按设想,B中无障碍物,D中有障碍物,角色矩形处于A位置,是可以靠近B的,D不能影响,所以减去一个像素,使得tile2的tile坐标仍然是角色矩形左上角所在的tile坐标。其他三个方向也是如此。

在设置角色的移动速度时,移动速度最好能够整除tile的宽度,比如tile的宽度为32,那么移动速度设为2或4等,这样不会产生死角(角色被困住,无法向其他方向移动)。

现在碰到一个问题,没有解决。按下方向键,角色移动的距离是速度的倍数,比如设置速度为2,但由于按下方向键的时间长短不一,移动的距离可能为4,8,12等。如果地图的某个地方有一扇门,有时候会出现走过头,退回来又退多了的情况。要是把按键改成按下再抬起,虽然每次的移动距离一定,但角色走的有点“慢”。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: