2012-01-25 84 views
1

我想创建一个pacman游戏来学习XNA,但是我碰到了一些问题以使碰撞检测工作。游戏是基于瓦片的,其中1是墙壁,0是可步行的。 然后,它会将您正在站立的拼图加上其周围的4个拼图,并且如果它与其中一个碰撞并且拼块值不为0,它会将位置重置为移动之前的位置。由于某种原因,但它不起作用,它会随机卡住,有时我甚至可以移动墙壁。 enter image description herePacman碰撞检测

这里是我的碰撞检测:

var oldPos = Position; 
    // Updates the Position 
    base.Update(theGameTime, mSpeed, mDirection); 

    // Test Collidetion 
    Rectangle objRect = new Rectangle((int)Position.X, (int)Position.Y, 32, 32); 
    bool isCollided = false; 
    Vector2 curTitle = GetCurrentTitle(); 

    // Test UP, DOWN, LEFT, RIGHT 
    int tile; 
    Rectangle testRect; 

    if ((int)curTitle.Y < 0 || (int)curTitle.X < 0 || (int)curTitle.Y >= map.MapSizeWidth - 1 || (int)curTitle.X >= map.MapSizeHeight - 1) 
     isCollided = true; 

    if (!isCollided) 
    { 
     tile = map.Tiles[(int)curTitle.Y, (int)curTitle.X]; 
     testRect = new Rectangle(((int)curTitle.X) * map.TileSize, ((int)curTitle.Y) * map.TileSize, map.TileSize, map.TileSize); 
     if (tile != 0 && rectangle_collision(testRect, objRect)) 
      isCollided = true; 

     if (curTitle.Y != 0) 
     { 
      tile = map.Tiles[(int)curTitle.Y - 1, (int)curTitle.X]; 
      testRect = new Rectangle(((int)curTitle.X) * map.TileSize, ((int)curTitle.Y - 1) * map.TileSize, map.TileSize, map.TileSize); 
      if (tile != 0 && rectangle_collision(testRect, objRect)) 
       isCollided = true; 
     } 

     tile = map.Tiles[(int)curTitle.Y + 1, (int)curTitle.X]; 
     testRect = new Rectangle(((int)curTitle.X) * map.TileSize, ((int)curTitle.Y - 1) * map.TileSize, map.TileSize, map.TileSize); 
     if (tile != 0 && rectangle_collision(testRect, objRect)) 
      isCollided = true; 

     if (curTitle.X != 0) 
     { 
      tile = map.Tiles[(int)curTitle.Y, (int)curTitle.X - 1]; 
      testRect = new Rectangle(((int)curTitle.X - 1) * map.TileSize, ((int)curTitle.Y) * map.TileSize, map.TileSize, map.TileSize); 
      if (tile != 0 && rectangle_collision(testRect, objRect)) 
       isCollided = true; 
     } 

     tile = map.Tiles[(int)curTitle.Y, (int)curTitle.X + 1]; 
     testRect = new Rectangle(((int)curTitle.X + 1) * map.TileSize, ((int)curTitle.Y) * map.TileSize, map.TileSize, map.TileSize); 
     if (tile != 0 && rectangle_collision(testRect, objRect)) 
      isCollided = true; 
    } 
    if (isCollided) 
     Position = oldPos; 

任何一个能看到为什么我的碰撞检测是不工作?

编辑:我已经上传整个项目http://sogaard.us/Pacman.zip

+0

我不会允许它移动和移回来 - 我会阻止它移动在第一个地方 - 方式更有效,可能会提供更好。 – niico

回答

1

我不知道这是否是引起充分的问题。但是,在你的第三个瓷砖检查(你在哪里检查瓷砖),你再次检查瓷砖。

在这里,这部分:

tile = map.Tiles[(int)curTitle.Y + 1, (int)curTitle.X]; 

在下一行你仍然有这个PARAMS为testRect内:

((int)curTitle.Y - 1) * map.TileSize 

应该是:

((int)curTitle.Y + 1) * map.TileSize 

完全纠正片段:

tile = map.Tiles[(int)curTitle.Y + 1, (int)curTitle.X]; 
    testRect = new Rectangle(((int)curTitle.X) * map.TileSize, ((int)curTitle.Y + 1) * map.TileSize, map.TileSize, map.TileSize); 
    if (tile != 0 && rectangle_collision(testRect, objRect)) 
     isCollided = true; 

希望这有助于:)

0

这行看起来很奇怪对我说:

testRect = new Rectangle(
    ((int)curTitle.X) * map.TileSize, 
    ((int)curTitle.Y) * map.TileSize, 
    map.TileSize, 
    map.TileSize); 

你为什么乘以X以TileSize Y坐标?

我不知道Rectangle的参数应该是什么意思,但我认为前两个是位置和最后两个宽度和高度。我猜你的意思是写

testRect = new Rectangle(
    ((int)curTitle.X), 
    ((int)curTitle.Y), 
    map.TileSize, 
    map.TileSize); 
+0

我把标题大小多重化的原因是因为curTitle.X是标题编号而不是标题的位置,每个标题都是map.TileSize * map.TileSize,因此标题3,2的起始位置是(3 * map。 TileSize),(2 * map.TileSize) – Androme

+0

在逻辑世界坐标(瓦片索引)中工作会更好,而不是屏幕坐标(瓦片大小)用于碰撞检测。可以根据瓦片计算pacman的位置指数? – MattDavey

+0

@DoomStone:这很有道理。在这种情况下,我不会立即看到错误。 – blubb