2013-08-16 42 views
-1

我想提前抱歉我要發佈的代碼量,但我似乎無法讓我的碰撞檢測工作,玩家和物體通過彼此當我玩測試時沒有任何效果。2D每個像素的碰撞檢測不起作用

我收到0個警告或錯誤,但播放器playerBot對象似乎不與我從GLEED2D導入的任何級別項目交互。

我做的一件事是將我的項目的矩形和顏色數組的值存儲在列表中,以便它們都可以很容易地迭代,也許這是問題的根源。

如果你能發現我的代碼不工作,我將非常感激。我刪除了絕對不相關的任何代碼,並且如果有幫助的話,我將使用GLEED2D 1.3運行VS 2010。

再次感謝。

// Item Class ImageItem Downcast 
public class ImageItem : Item 
{ 
    public Texture2D Texture; 
} 

// Level 
Level level; 

// Ints 
int iNumOfItems = 0; 
int iTextureDataListNum = 0; 
int iRectangleListNum = 0; 

// Lists 
List<Color []> itemTextureDataList = new List<Color[]>(); 
List<Rectangle> itemRectangleList = new List<Rectangle>(); 

protected override void Initialize() 
{ 
    if (filename.Length > 0) level = Level.FromFile(filename, Content); 
    else level = Level.FromFile("level1.xml", Content); 

    foreach (Layer layer in level.Layers) 
    { 
     foreach (Item item in layer.Items) 
     { 
      iNumOfItems =+ 1; 
     } 
    } 

    // Creates Player Ship 
    playerBot = new Player(new Vector2(400f, 240f), new Vector2(0f, 0f)); 

    base.Initialize(); 
} 

protected override void LoadContent() 
{ 
    Texture2D pixel = new Texture2D(GraphicsDevice, 1, 1, false, SurfaceFormat.Color); 
    pixel.SetData(new[] { Color.White }); 
    spriteBatch = new SpriteBatch(GraphicsDevice); 

    // Player Bot 
    playerBot.LoadContent(Content, "Images/Player Bot Sprite Sheet", 40, 40, 4); 

    // Assigns level textures color data to array 
    foreach (Layer layer in level.Layers) 
    { 
     foreach (Item item in layer.Items) 
     { 
      ImageItem imageItem = item as ImageItem; 
      if (imageItem != null) 
      { 
       Texture2D texture = imageItem.Texture; 

       itemTextureDataList[iTextureDataListNum] = new Color[imageItem.Texture.Width * imageItem.Texture.Height]; 
       imageItem.Texture.GetData(itemTextureDataList[iTextureDataListNum]); 
       iTextureDataListNum++; 
      } 
     } 
    } 

    // Creates a rectangle for every level texture 
    foreach (Layer layer in level.Layers) 
    { 
     foreach (Item item in layer.Items) 
     { 
      ImageItem imageItem = item as ImageItem; 
      if (imageItem != null) 
      { 
       itemRectangleList[iRectangleListNum] = new Rectangle((int)imageItem.Position.X, (int)imageItem.Position.Y, imageItem.Texture.Width, imageItem.Texture.Height); 
       iRectangleListNum++; 
      } 
     } 
    } 

    spriteBatch = new SpriteBatch(GraphicsDevice); 
} 

protected override void Update(GameTime gameTime) 
{ 
    // Player Update 
    playerBot.Update(gameTime); 
    ((Sprite)playerBot).Update(gameTime); 

    // Check for player collisons with level 
    for (int i = 0; i < iNumOfItems - 1; i++) 
    { 
     if (IntersectPixels(playerBot.colRectangle, playerBot.textureDataArray, itemRectangleList[i], itemTextureDataList[i]) == true) 
     { 
      playerBot.StopMovement(); 
     } 
    } 

    base.Update(gameTime); 
} 

// Level Collision Detection Method 

static bool IntersectPixels(Rectangle rectangleA, Color[] dataA, Rectangle rectangleB, Color[] dataB) 
{ 
    // Find the bounds of the rectangle intersection 
    int top = Math.Max(rectangleA.Top, rectangleB.Top); 
    int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom); 
    int left = Math.Max(rectangleA.Left, rectangleB.Left); 
    int right = Math.Min(rectangleA.Right, rectangleB.Right); 

    // Check every point within the intersection bounds 
    for (int y = top; y < bottom; y++) 
    { 
     for (int x = left; x < right; x++) 
     { 
      // Get the color of both pixels at this point 
      Color colorA = dataA[(x - rectangleA.Left) + (y - rectangleA.Top) * rectangleA.Width]; 
      Color colorB = dataB[(x - rectangleB.Left) + (y - rectangleB.Top) * rectangleB.Width]; 

      // If both pixels are not completely transparent 
      if (colorA.A != 0 && colorB.A != 0) 
      { 
       // Then an intersection has been found 
       return true; 
      } 
     } 
    } 

    // No intersection fond 
    return false; 
} 

// Sprite類

public void Update(GameTime gameTime) 
{ 
    textureDataArray = new Color[texture.Width * texture.Height]; 
    texture.GetData(textureDataArray); 

//播放器類

public void StopMovement() 
{ 
    velocity.X *= -1; 
    velocity.Y *= -1; 
} 
+2

如果您要從Gamedev複製並粘貼您的問題(並且不要這麼做;如果它屬於此處,請在標記中進行遷移),至少避免複製您的downvote。 – geoffspear

+1

繪製邊界矩形以及在不讀取代碼的情況下,我使用的第一個錯誤是沒有移動邊界矩形與對象,**編輯**只是忽略了您的代碼,您甚至不使用BoundingRectangle ...爲什麼不? – Sayse

+0

Wooble,對不起的禮儀感到遺憾,但沒有人在遊戲開發中幫助我解決了我的問題,而且我一直在這個問題上困擾了好幾天。我可以向你保證我不會再這樣做。 Saysa,我使用紋理的高度/寬度創建了我自己的Rectangle並添加了正確的原點Math。雖然我懷疑我是否做到了這一點,但你如何建議實現這個BoundingRectangle?謝謝你們的幫助,我一直把我的頭髮拉出來。 –

回答

1

我就是這裏說的第一件事情,你的目標應該是更對象在你的方法面向。在項目列表旁邊存儲紋理列表和矩形列表是一種「不良」技術,並且在調試時最終會引發大量頭痛問題。所以首先,不是有一個Color []列表和一個Rectangle列表,而是添加一個Color []和一個Rectangle到你的ImageItem類中,並用它們來處理,或者至少創建一個名爲具有矩形和顏色[]的「CollisionData」並將它們存儲在單個列表中。

其次,請注意,有一個Rectangle.Intersect(矩形A,矩形B)可以獲得您的矩形交集。所以你可以通過使用它來整理你的代碼。

您的顏色檢查可以簡化爲(ColorA.A * ColorB.A!= 0),因爲如果爲零,則 會導致結果爲零。

關於沒有得到任何錯誤,在碰撞檢查循環的開始處放置一個斷點。應用程序是否中斷?如果是,iNumItems的價值是什麼? (你可以將鼠標懸停在它上面以查看當前打破點的值)。如果不是,那麼代碼段沒有被達到。將另一個斷點放回原處並稍微延後一點,直至遇到它,然後找出代碼未執行的原因。

+0

非常感謝Steve,這是我一直在尋找的建議,非常感謝。這個編碼業務是棘手的,但我高興地發現,感謝您的幫助! –

+0

變成imageitem = null,因此從未將紋理數據添加到列表中。我已經做出了您所建議的更改,並且我的代碼看起來更加流暢,但我不知道如何讓imageItem不爲null。 –

+1

它必須是您的列表中的項目不是類(並且不是派生自)ImageItem所以「ImageItem imageItem = item as ImageItem;」設置爲NULL,而不是像你希望的那樣強制轉換。 –