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 中的每个正方形(一旦循环完成)将完全在视图的边界内,不与数组中的任何其他按钮相交,并且完全在 playerRect rect 的边界之外,即屏幕中央的一个 120 x 120 正方形。我的代码错了吗?因为我没有这些功能。

编辑:事实上,我确实得到了这种方法所需的特性之一:没有正方形与 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 中的所有按钮不与按钮相交,而不仅仅是一个。

另外,初始化按钮的框架是什么?也许这将是一个更好的解决方案:

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包含三个带有这些框架的按钮 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 重叠。

于 2011-11-20T02:55:23.620 回答
0

最后,这奏效了:(结合了 Rob Lourens 和 rob mayoff 的精彩回答——谢谢大家,在这里,你们每个人都有一个赞成票!:))

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 回答