1

アプリでは、実行するたびに正方形にランダムなフレームを割り当てます。私はこのロジックを使用して確認します


a)各正方形がプレーヤーに近すぎない
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の各正方形は(ループが完了すると)完全にビューの境界の内側にあり、配列内の他のボタンと交差せず、playerRectrectの境界の完全に外側にあると予想されます。 、画面中央の120x120の正方形です。私のコードは間違っていますか?私はこれらの機能のどれも得られないからです。

編集:私は実際、このメソッドの望ましい特性の1つを取得しています。つまり、playerRectと交差する正方形はありません。しかし、私はまだ互いに重なり合っている正方形と部分的に見えない正方形を取得します。

編集2:

ネストされたforループに次の変更を加えました。

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;
            }

そして今、正方形は常にビューのためにわずかに変更された(小さい)長方形内にあり、プレーヤーの正方形と交差することはありません。わーい。しかし、それらはまだ互いの上に表示されます。なんで?

4

3 に答える 3

1

それは問題ではありません、CGRectIntersectsRectそれはあなたの論理の問題です。内側のループがボタンと交差しない単一のUIButtonを見つけると、ボタンに対して生成されたランダムな座標を受け入れます。squareArrayのすべてのボタンが、1つだけでなく、ボタンと交差しないようにする必要があります。

また、初期化されたボタンのフレームは何ですか?多分これはより良い解決策になるでしょう:

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);
}

私はそれをまったくテストしていないことに注意してください。また、状況によっては、ボタンの有効な位置がない場合、これは永久にループする可能性があります。問題によっては、すべてを完全にランダムに配置するよりも良い解決策があるかもしれません。

于 2011-11-20T02:19:35.887 に答える
1

これらのフレームsquareArrayに3つのボタン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ます。

2番目のパスでは、b == Bつまり[b isEqual:button]、何もしません。

3番目の(そして最後の)パスで、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し、それがfalseであることを確認して、do/whileループを終了します。ボタンBがボタンAと重なっています。

于 2011-11-20T02:55:23.620 に答える
0

結局、これはうまくいきました:(ロブ・ローレンスとロブ・メイオフの素晴らしい答えの組み合わせ-みんなに感謝します、そしてここで、あなた方一人一人が賛成票を持っています!:))

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;
            }
        }
}
于 2011-11-20T03:20:24.143 に答える