CGRectIntersectsRect 逻辑不准确
在应用程序中,每次运行时我都会向方块提供随机帧。我使用这个逻辑来确保
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 矩形的边界,该矩形是屏幕中心的一个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;
}
现在,正方形始终位于稍微修改的(较小的)视图矩形内,并且它们从不与玩家正方形相交。耶。但它们仍然出现在彼此之上。为什么?
In an app I give random frames to squares every time it is run. I use this logic to make sure
a) each square is not too close to the player
and
b) each square is contained inside the view of the screen
c) no square touches any other square
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);
}
With this code, I would expect that each square in squareArray would be (once the loop was complete) completely inside the boundaries of the view, not intersecting with any other of the buttons in the array, and completely outside the boundaries of the playerRect rect, which is a square 120 x 120 in the center of the screen. Is my code wrong? Because I get none of these functionalities.
Edit: I do in fact get one of the desired traits of this method: no square ever intersects playerRect. But I still get squares overlapping each other and squares that are partially out of the view.
Edit 2:
I have made these changes to the nested for loop:
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;
}
And now the squares always are within the slightly modified (smaller) rect for the view, and they never intersect the player square. Yay. But they still appear on top of each other. Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这不是 CGRectIntersectsRect 的问题,而是你的逻辑的问题。当内部循环找到一个不与按钮相交的 UIButton 时,您接受为按钮生成的随机坐标。您需要确保 squareArray 中的所有按钮都不与按钮相交,而不仅仅是一个。
另外,按钮的框架初始化为什么?也许这将是一个更好的解决方案:
请注意,我根本没有测试过。此外,根据具体情况,如果按钮没有有效位置,则可能会永远循环。根据您的问题,可能有比完全随机放置所有内容更好的解决方案。
It's not a problem with
CGRectIntersectsRect
, it's a problem with your logic. When the inner loop finds a single UIButton that does not intersect button, you accept the random coords generated for button. You need to ensure that all the buttons in squareArray don't intersect button, not just one.Also, what are the frames of the buttons initialized to? Maybe this would be a better solution:
Note that I haven't tested that at all. Also, depending on the situation, this could loop forever if there is no valid position for a button. There may be a better solution than placing everything completely randomly, depending on your problem.
假设
squareArray
包含三个具有以下框架的按钮 A、B 和 C:请注意,A 和 B 重叠,但 A 和 B 不重叠 C。现在考虑当
按钮==B
。第一次通过内部循环时,
b == A
,因此您检测到CGRectIntersectsRect(b.frame, button.frame)
并设置shouldContinue = YES< /代码>。
在第二遍中,
b == B
表示[b isEqual:button]
,因此您什么也不做。在第三次(也是最后一次)传递中,
b == C
。您发现 CGRectIntersectsRect(b.frame, button.frame) 为 false(因为B.frame
不与C.frame
相交),并且CGRectIntersectsRect(button.frame, playerRect)
为 false,并且!CGRectContainsRect(CGRectMake(10, 10, 300, 460), Button.frame)
为 false。所以你设置了shouldContinue = NO。然后内循环退出。您测试
shouldContinue
,发现它是 false,然后退出 do/while 循环。左按钮 B 与按钮 A 重叠。Suppose
squareArray
contains three buttons A, B, and C with these frames:Note that A and B overlap, but A and B do not overlap C. Now consider what happens in your inner loop when
button == B
.On the first pass through the inner loop,
b == A
, so you detectCGRectIntersectsRect(b.frame, button.frame)
and setshouldContinue = YES
.On the second pass,
b == B
which means[b isEqual:button]
, so you do nothing.On the third (and final) pass,
b == C
. You find thatCGRectIntersectsRect(b.frame, button.frame)
is false (becauseB.frame
does not intersectC.frame
), andCGRectIntersectsRect(button.frame, playerRect)
is false, and!CGRectContainsRect(CGRectMake(10, 10, 300, 460), button.frame)
is false. So you setshouldContinue = NO
.Then the inner loop exits. You test
shouldContinue
, find that it's false, and exit the do/while loop. You have left button B overlapping button A.最后,这成功了:(罗布·劳伦斯和罗布·梅奥夫的精彩答案的结合-谢谢大家,在这里,你们每个人都投了赞成票!:))
In the end, this worked: (a combination of the wonderful answers of Rob Lourens and rob mayoff- thanks guys, and here, each of you have an upvote! :) )