2011-11-20 138 views
1

在應用程序中,每次運行時我都會將隨機幀放到正方形中。我用這個邏輯,以確保CGRectIntersectsRect邏輯錯誤

一)每平方米是不是太靠近玩家

B)每平方包含在屏幕 C的視圖中)沒有方接觸的任何其他方

for(UIButton* button in squareArray) { 
    BOOL shouldContinue = YES; 
    do { 
     int randX = arc4random() % 321; 
     int randY = arc4random() % 481; 
     button.frame = CGRectMake(randX, randY, button.frame.size.width, button.frame.size.height); 
     CGRect playerRect = CGRectMake(100, 180, 120, 120); 
     for(UIButton* b in squareArray) 
      if(!CGRectIntersectsRect(b.frame, button.frame) && 
       !CGRectIntersectsRect(button.frame, playerRect) && 
       CGRectContainsRect(self.view.frame, button.frame)) { 
       shouldContinue = NO; 
      } 
    } while (shouldContinue); 
} 

使用此代碼,我期望squareArray中的每個方塊都將(完成循環後)完全位於視圖的邊界內,不與數組中的任何其他按鈕相交,並且完全位於playerRect矩形的邊界,它是屏幕中心的120 x 120方形。我的代碼錯了嗎?因爲我沒有得到這些功能。

編輯:我確實得到了這個方法的一個理想的特徵:沒有正方形與playerRect相交。但我仍然看到方塊互相重疊,並且正方形部分偏離視野。

編輯2:

我做這些更改,以嵌套的循環:

for(UIButton* b in squareArray) 
      if(![b isEqual:button]) { 
       if(CGRectIntersectsRect(b.frame, button.frame) || 
        CGRectIntersectsRect(button.frame, playerRect) || 
        !CGRectContainsRect(CGRectMake(10, 10, 300, 460), button.frame)) 
        shouldContinue = YES; 
       else 
        shouldContinue = NO; 
      } 

而且現在的廣場一直是稍微修改(小)矩形的視圖中,他們從來沒有相交玩家廣場。好極了。但它們仍然相互重疊。爲什麼?

+0

您沒有提出問題或解釋您認爲您的代碼有問題。 –

+0

Bahahaha對不起,我實際上在問一個問題之前意外地發佈了它,因爲我很匆忙。正在更新... –

回答

0

最後,這工作:(Rob Lourens和搶mayoff的精彩答案的組合 - 感謝球員,在這裏,你們每個人都有一個upvote!:))

for(int iii = 0; iii < [squareArray count]; iii++) { 

    int randX = arc4random() % 321; 
    int randY = arc4random() % 481; 

    [(UIButton*)[squareArray objectAtIndex:iii] setFrame:CGRectMake(randX, randY, [(UIButton*)[squareArray objectAtIndex:iii] frame].size.width, [(UIButton*)[squareArray objectAtIndex:iii] frame].size.height)]; 

    CGRect playerRect = CGRectMake(40, 120, 150, 150); 

    for(UIButton* b in squareArray) 

     if(![b isEqual:[squareArray objectAtIndex:iii]]) { 

      if(CGRectIntersectsRect(b.frame, [(UIButton*)[squareArray objectAtIndex:iii] frame])) 
      { 
       iii--; 
       break; 
      } else if(CGRectIntersectsRect([(UIButton*)[squareArray objectAtIndex:iii] frame], playerRect)) { 
       iii--; 
       break; 
      } else if(![self checkBounds:[(UIButton*)[squareArray objectAtIndex:iii] frame]]) { 
       iii--; 
       break; 
      } 
     } 
} 
1

這不是CGRectIntersectsRect的問題,這是您的邏輯問題。當內部循環找到一個不相交的UIButton按鈕時,您接受爲按鈕生成的隨機座標。您需要確保squareArray中的所有按鈕不會與按鈕相交,而不僅僅是一個。

另外,初始化按鈕的框架是什麼?也許這將是一個更好的解決方案:

for (int i=0; i<[squareArray count]; i++) { 
    UIButton* button = [squareArray objectAtIndex:i]; 
    BOOL shouldContinue = NO; 
    do { 
     int randX = arc4random() % 321; 
     int randY = arc4random() % 481; 
     button.frame = CGRectMake(randX, randY, button.frame.size.width, button.frame.size.height); 
     CGRect playerRect = CGRectMake(100, 180, 120, 120); 
     for(int j=0; j<i; j++) 
      UIButton *b = [squareArray objectAtIndex:j]; 
      if(CGRectIntersectsRect(b.frame, button.frame) || 
       CGRectIntersectsRect(button.frame, playerRect) || 
       !CGRectContainsRect(self.view.frame, button.frame)) { 
       shouldContinue = YES; 
      } 
    } while (shouldContinue); 
} 

請注意,我還沒有測試過。另外,根據情況,如果沒有有效的按鈕位置,這可能會永遠循環。根據您的問題,可能會有比將所有內容完全隨機放置的更好的解決方案。

+0

通過IB初始化框架,因爲squareArray中的每個方塊都是UIButton的IBOutlet,所以它們都有默認位置,我只是想隨機化它們。 –

+1

我已經做了一些改變,請參閱我的編輯 –

+0

你確定你已經在廣場上的所有廣場陣列?如果他們來自一個筆尖,也許有一些你沒有重新定位? –

1

假設squareArray包含三個按鈕A,B和C與這些框架:

A.frame == CGRectMake(10,10,10,10) 
B.frame == CGRectMake(10,10,10,10) 
C.frame == CGRectMake(20,10,10,10) 

需要注意的是A和B的重疊,但A和B不重疊C.現在考慮在你的內部循環會發生什麼當時button == B

第一次通過內循環,b == A,所以你檢測CGRectIntersectsRect(b.frame, button.frame)並設置shouldContinue = YES

第二次通過,b == B這意味着[b isEqual:button],所以你什麼都不做。

第三次(也是最後一次)通過,b == C。您發現CGRectIntersectsRect(b.frame, button.frame)爲假(因爲B.frame不與C.frame相交),並且CGRectIntersectsRect(button.frame, playerRect)爲假,並且!CGRectContainsRect(CGRectMake(10, 10, 300, 460), button.frame)爲假。所以你設置了shouldContinue = NO

然後內循環退出。您測試shouldContinue,發現它是錯誤的,並退出do/while循環。你已經離開了按鈕B重疊按鈕A.

+0

所以,換句話說,刪除你設置shouldContinue = NO的行。 –

+0

對於爲什麼這種方式不起作用我有一個很長的解釋,我正準備發佈它並尋求更多的幫助,但後來我決定對它進行強化並將其解決。刪除該行將不起作用,因爲即使滿足條件,shouldContinue在它不滿意時仍然爲YES,並且您將獲得無限循環。我剛剛發佈了工作解決方案。 –