2013-07-28 28 views
-3

我正在研究XNA中的碰撞。有些原因,儘管我嘗試了很多次,但這並不奏效。如果我觸摸它,它會起作用。但有時候它會像發生碰撞一樣停止運行。它的工作方式是有五十個20像素×20像素的方塊。如果你的廣場以任何方式接觸另一個廣場,那麼遊戲結束。碰撞代碼不起作用,儘管有幾次檢查

checkcollision() 
    { 
     for (int i = 0; i < 50; i++) 
     { 
      if ((loc.X + me.Width > enemyloc[i].X) && (loc.Y + me.Height > enemyloc[i].Y) && (loc.Y < enemyloc[i].Y) && (loc.X < enemyloc[i].X)) { return true; } 
      if ((loc.X > enemyloc[i].X) && (enemyloc[i].X + enemy[i].Width > loc.X) && (loc.Y + me.Height > enemyloc[i].Y) && (loc.Y < enemyloc[i].Y)) { return true; } 
      if ((loc.X > enemyloc[i].X) && (loc.X < enemyloc[i].X + enemy[i].Width) && (loc.Y > enemyloc[i].Y) && (loc.Y < enemyloc[i].Y + enemy[i].Height)) { return true; } 
      if ((loc.X < enemyloc[i].X) && (loc.X + me.Width > enemyloc[i].X) && (loc.Y < enemyloc[i].Y) && (loc.Y < enemyloc[i].Y + enemy[i].Height)) { return true; } 
     } 
     return false; 
    } 
+1

嘗試。 –

回答

2

我同意這個代碼看起來有點太複雜了。我建議將你的敵方和玩家碰撞盒作爲Rectangle struct的實例。矩形結構提供了一個名爲Contains方法,其被定義爲:

public bool Contains(int x, int y); 

如果在x和y定義的點在矩形中存在此方法將返回真。因此,使用這種結構的代碼會變得簡單得多:使用調試器

public bool checkcollision(Rectangle player) 
{ 
    for (int i = 0; i < enemy.Length; i++) 
    { 
     if (enemy[i].Contains(player.Left, player.Top) 
      || enemy[i].Contains(player.Right, player.Top) 
      || enemy[i].Contains(player.Left, player.Bottom) 
      || enemy[i].Contains(player.Right, player.Bottom)) 
     { 
      return true; 
     } 
    } 
    return false; 
} 
+0

謝謝你,這其實很有幫助 – user2620543

+0

歡迎你。如果你有時間,可否請您將我的答案標記爲正確的?謝謝。 –

+0

感謝您標記接受的答案。 –

0

正如我在評論說,這是太難讀。雖然我不會聲稱它是問題(使用Mitch小麥建議的調試器),但它肯定可以解決!

首先,我們概述一個單軸X的碰撞檢測。我們不是首先查找碰撞,而是尋找沒有碰撞。有「不是只有當」(玩家在敵人的左邊)或(敵人在玩家的左邊)「時纔會沿着X軸發生碰撞。 (原因是,如果這些都不是真的,那麼「對敵人的球員」必須是真實的 - 如果需要使用圖片)

令p =播放機,E =敵人,然後有一個沒有碰撞 [唯一]時(pX + pW < eX)|| (e.X + e.W < p.X)。這意味着在相反/否定的情況下發生碰撞!

因此,我們可以寫出碰撞方法

bool Collides (IEntityBox p, IEntityBox e) { 
    bool noCollisionX = (p.X + p.W < e.X) || (e.X + e.W < p.X); 
    bool collisionX = !noCollisionX; 
    bool noCollisionY = (p.Y + p.H < e.Y) || (e.Y + e.H < p.Y); 
    bool collisionY = !noCollisionY; 
    // not that the collision on BOTH axises must be fulfilled 
    return collisionX && collisionY; 
} 

註釋(留給讀者作爲練習):

  1. IEntityBox具有X/Y和W/H的屬性和(0, 0)假定爲屏幕的左上角。爲您的實施使用正確的類型/ propeties。如果玩家與其他實體之間的定位是統一的,則更簡單。

  2. 表達式可以被重寫(和De Morgan's可以被應用)來清理它一點點。簡單的崩潰將消除所有變量,但保持「輕鬆」閱讀。

  3. 如果noCollisionX(暗示!collisionX)爲真,我們不需要計算noCollisionY。如果摺疊,這可以使用if/else或短路評估。

使用同樣清理:

bool PlayerCollidesWithAnyEnemy() { 
    foreach (var e in enemies) { // avoid hard-coding numbers 
    if (Collides(player, e)) { 
     return true; 
    } 
    } 
    return false; 
} 
// .. 
var playerOopsed = PlayerCollidesWithAnyEnemy(); 

或者,使用LINQ:

var playerOopsed = enemies.Any(e => Collides(player, e));