我有一个模型对象,存储一个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];
}