0

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

0 回答 0