2012-06-02 65 views
0

我是XNA和C#的新品牌(我在2天前開始了,所以請原諒這種馬虎的編程),而且我遇到了一個我正在做的簡單遊戲的問題。我似乎無法在任何在線教程中找到解決方案。我試圖利用矩形碰撞檢測,但我無法正常工作。角色完全落在地板上,似乎在任何地方都沒有碰撞。我在這裏找不到我的邏輯錯誤。下面我發佈了一些與碰撞檢測有關的代碼。如有必要,我可以發佈更多內容預先感謝您的幫助!二維碰撞檢測不起作用XNA C#

Level.cs

//The method below is called in the initial LoadContent method in Game1.cs. 'LoadBlocks()' is supposed to read in a text file and setup the level's "blocks" (the floor or platforms in the game). 

public void LoadBlocks(int level){ 
    if (level == 0) 
     { 
      fileName = "filepath"; 
     } 

     System.IO.StreamReader file = new System.IO.StreamReader(fileName); 
     while ((line = file.ReadLine()) != null) 
     { 
      for (int i = 0; i < 35; i++) 
      { 
       rectBlock = new Rectangle((int)positionBlock.X, (int)positionBlock.Y, width/30, height/30); 

       if (line.Substring(i, 1).Equals(",")) 
       { 
        positionBlock.X += (width/100) * 24; 
       } 
       if (line.Substring(i, 1).Equals("#")) 
       { //block -> (bool isPassable, Texture2D texture, Rectangle rectangle, Vector2 position) 
        block = new Block(false, textureBlock, rectBlock, positionBlock); 
        blocks.Add(block); 
        positionBlock.X += (width/100) * 24; 
       } 
      } 


      positionBlock.Y += (height/100) * 8; 
      positionBlock.X = 0; 
     } 
    } 

//This method below updates the character 'bob' position and velocity. 
public void UpdatePlayer() 
    { 
     bob.position += bob.velocity; 
     bob.rectangle = new Rectangle((int)bob.position.X, (int)bob.position.Y, width/30, height/30); 

     float i = 1; 
     bob.velocity.Y += 0.15f * i; 
     foreach (Block block in blocks) 
     { 
      if (bob.isOnTopOf(bob.rectangle, block.rectangle)) 
      { 
       bob.velocity.Y = 0f; 
       bob.hasJumped = false; 
      } 
     } 
    } 

Character.cs

//Here is my whole Character class for 'bob' 

public class Character 
{ 
    int height = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height; 
    int width = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width; 

    int health; 
    String name; 
    bool gender; 
    Texture2D texture; 
    public Vector2 position; 
    public Vector2 velocity; 
    public bool hasJumped; 
    public Rectangle rectangle; 

    public Character(int newHealth, String newName, bool newGender, Texture2D newTexture, Vector2 newPosition) 
    { 
     health = newHealth; 
     gender = newGender; 
     name = newName; 
     texture = newTexture; 
     position = newPosition; 
     hasJumped = true; 
     rectangle = new Rectangle(0,0, width/30,height/30); 
     velocity = Vector2.Zero; 
    } 

    public bool isOnTopOf(Rectangle r1, Rectangle r2) 
    { 
     const int penetrationMargin = 5; 

     return (r1.Bottom >= r2.Top - penetrationMargin && 
      r1.Bottom <= r2.Top && 
      r1.Right >= r2.Left + 5 && 
      r1.Left <= r2.Right - 5); 

    } 


    public void Draw(SpriteBatch spriteBatch) 
    { 
     spriteBatch.Draw(texture, rectangle,null, Color.White,0,position,SpriteEffects.None,0); 
    } 

} 

很抱歉,如果這是太多貼出代碼或者是混亂的,但任何幫助是極大的讚賞!謝謝!

回答

3

您的交叉口測試條件似乎是不正確的,至少。有可能是其他問題的代碼(有幾個只是給快速看一下它),但是讓我們專注於此:

r1.Bottom >= r2.Top - penetrationMargin && 
r1.Bottom <= r2.Top && 
r1.Right >= r2.Left + 5 && 
r1.Left <= r2.Right - 5; 

首先,不要在代碼對你的收藏中有哪些存在。 Xna矩形有一個Intersects方法,所以取消代碼並使用它。

我們將看看情況呢:

r1's Bottom is below r2's Top minus a margin AND 
r1's Bottom is above r2's Top AND (...) 

這已經是不可能的。 r1.Bottom不能爲以下和以上 r2.Top。

此外,即使所有的比較都是正確的,你在每個地方都使用AND(& &),這意味着只有當它們全都爲真時,條件才爲真。基本上,你沒有測試交叉路口,你正在測試集裝箱,即你正在測試r1完全在r2內。相交測試將使用OR(||)而不是AND(& &)來加入條件。

但是,儘管您可能想出於教育目的自己編寫代碼,但從工程角度來看,最好的解決方案是使用庫提供的內容,這裏是Rectangle.Intersects。

+0

謝謝你的幫助。這種方式要簡單得多。 – Derek

0

我想通了,但我不知道爲什麼這實際上起作用。我的繪畫方法出了點問題。我本來有:

spriteBatch.Draw(texture, rectangle, null, Color.White, 0, position, SpriteEffects.None, 0); 

我的方法,但後來我改變這

spriteBatch.Draw(texture, rectangle, Color.White); 

,現在一切工作正常。

+0

不知道爲什麼格式不起作用,對不起! – Derek