我有一个模型对象,它存储一组 X、Y 位置。这些位置以网格方式排列。该模型还有一个 givePositionForBlock 方法,我用它来设置在屏幕上生成的图块的位置。
它随机从数组中取出一个位置,并检查距离是否与用户控制的某个其他图块足够远。如果距离不够远,它会将位置放回数组中并尝试另一个。正是这种方法导致了冻结。没有错误日志或任何东西。它总是在 emptyBlocks 数组几乎为空的同时发生(大约 3 次中的 1 次)。
我意识到这是因为随着网格被填满,找到离用户控制的图块足够远的图块变得更加困难。
我试图通过在填充网格时减少 spawnOffset 来解决这个问题,并在某个点简单地忽略 spawnOffset 规则。但它似乎并不总是有效。如果我删除 while 循环,它工作正常。但是我需要进行检查,否则在播放时对象可能会在用户面前产生。
- (CGPoint) givePositionForBlock {
CGPoint position = [[self givePosition] CGPointValue];
BOOL generatedPositionOk = NO;
float spawnOffset = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ? 256: 128;
GameScene *scene = [GameScene sharedGameScene];
SnakePiece *snakeHead = [scene.tileArray objectAtIndex:0];
int tries = 0;
int maxtries = 50;
// decrease the minimum required distance as the grid gets filled
if ([emptyBlocks count] < 70 && [emptyBlocks count] > 35 ) {
spawnOffset = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ? 128: 64;
} else if ([emptyBlocks count] < 35 && [emptyBlocks count] > 20){
spawnOffset = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ? 64: 32;
} else if ([emptyBlocks count] < 20){
generatedPositionOk = YES;
}
// check if the position is far enough away.
while (generatedPositionOk == NO) {
if ((position.x > snakeHead.position.x+spawnOffset || position.x < snakeHead.position.x-spawnOffset) ||
(position.y > snakeHead.position.y+spawnOffset || position.y < snakeHead.position.y-spawnOffset )) {
generatedPositionOk = YES;
break;
} else {
//if not then put the position back in the array and take a new one.
//repeat until suitable position is found.
[self insertPositionInEmptyBlocksArray:position];
position = [[self givePosition] CGPointValue];
generatedPositionOk = NO;
tries++;
//maximum amount of times it can try to find a suitable position.
//if the max is exceeded use the position anyway
if (tries > maxtries) {
generatedPositionOk = YES;
break;
}
}
}
return position;
}
这是上面使用的 givePosition 方法。
- (NSValue *) givePosition {
int x;
CGPoint randomPointGl;
if ([emptyBlocks count] > 0) {
x = arc4random() % [emptyBlocks count];
randomPointGl = [[emptyBlocks objectAtIndex:x]CGPointValue];
[filledBlocks addObject:[NSValue valueWithCGPoint:randomPointGl]];
[emptyBlocks removeObjectAtIndex:x];
}
return [NSValue valueWithCGPoint:randomPointGl];
}