Препятствия с GameplayKit

Вот мой вопрос:

  • Как я могу конвертировать SKSpriteNode массив в массив GKObstacles так что агент может соответствующим образом избежать этих препятствий, используя goalToAvoidObstacles:(nonnull NSArray<GKObstacle *> *) maxPredictionTime:(NSTimeInterval) /?

Кажется, что способ, которым я создаю GKObstacle массив не позволяет GKGoal правильно определить их как препятствия, независимо от того, какой вес я придаю цели.

У меня сейчас несколько SKNode ы, которые добавляются к SKScene Глава Сцена. Каждый из этих узлов добавляется в массив, который я сохраняю, называемый Я настроил тест следующим образом, который работает довольно хорошо:

РАБОЧИЕ ПРЕПЯТСТВИЯ

- (void)didMoveToView:(nonnull SKView *)view {
    [super didMoveToView:view];

    // Add three obstacles in a triangle formation around the center of the scene.
    NSArray<GKObstacle *> *obstacles = @[
                                         [self addObstacleAtPoint:CGPointMake(CGRectGetMidX(self.frame),
                                                                              CGRectGetMidY(self.frame) + 150)],
                                         [self addObstacleAtPoint:CGPointMake(CGRectGetMidX(self.frame) - 200,
                                                                              CGRectGetMidY(self.frame) - 150)],
                                         [self addObstacleAtPoint:CGPointMake(CGRectGetMidX(self.frame) + 200,
                                                                              CGRectGetMidY(self.frame) - 150)],
                                         ];

    // The player agent follows the tracking agent.
    self.player = [[OPlayer alloc] initWithScene:self
                                                radius:50
                                              position:CGPointMake(CGRectGetMidX(self.frame),
                                                                   CGRectGetMidY(self.frame))];
    self.player.agent.behavior = [[GKBehavior alloc] init];
    [self.agentSystem addComponent:self.player.agent];

    // Create the seek goal, but add it to the behavior only in -setSeeking:.
    self.seekGoal = [GKGoal goalToSeekAgent:self.character];

    // Add an avoid-obstacles goal with a high weight to keep the agent from overlapping the obstacles.
    [self.player.agent.behavior setWeight:100 forGoal:[GKGoal goalToAvoidObstacles:obstacles maxPredictionTime:1]];

}

- (GKObstacle *)addObstacleAtPoint:(CGPoint)point {
    SKShapeNode *circleShape = [SKShapeNode shapeNodeWithCircleOfRadius:50];
    circleShape.lineWidth = 2.5;
    circleShape.fillColor = [SKColor grayColor];
    circleShape.strokeColor = [SKColor redColor];
    circleShape.zPosition = 1;
    circleShape.position = point;
    [self addChild:circleShape];

    GKCircleObstacle *obstacle = [GKCircleObstacle obstacleWithRadius:50];
    obstacle.position = (vector_float2){point.x, point.y};

    return obstacle;
}

Хотя это работает очень хорошо, проблема, с которой я сталкиваюсь, заключается в том, что я не могу заставить поведение идентифицировать SKNode массив тел, которые я имею в качестве препятствий. Я могу получить их только вручную GKCircleObstacle предметы для регистрации в качестве действительных препятствий, которых избегает агент. Причина в том, что это проблема, потому что я полагаюсь на многие препятствия, которые на самом деле не являются простыми кругами, а многоугольными структурами, которые являются сложными, а некоторые более простыми. Тем не менее, я пытался сделать следующее, но мой агент, похоже, не избежал каких-либо препятствий, SKNode сюда:

НЕ РАБОТАЮЩИЕ ПРЕПЯТСТВИЯ

NSArray *obstacles = [SKNode obstaclesFromNodePhysicsBodies:obstaclesArray];

/*
 The other code seen above
 */

// Add an avoid-obstacles goal with a high weight to keep the agent from overlapping the obstacles.
[self.player.agent.behavior setWeight:100 forGoal:[GKGoal goalToAvoidObstacles:obstacles maxPredictionTime:1]];

К сожалению, это, похоже, не работает, так как независимо от того, насколько высоко я установил вес, агент никогда не реагирует на обход препятствий. Вот журнал массива, который я передаю ему:

2016-07-24 22:32:24.907 <GAME>[1516:475581] obstacles: (
    "<GKPolygonObstacle: 0x14d20d70>",
    "<GKPolygonObstacle: 0x14d20e10>",
    "<GKPolygonObstacle: 0x14d20ba0>",
    "<GKPolygonObstacle: 0x14d20bb0>",
    "<GKPolygonObstacle: 0x14d20bc0>",
    "<GKPolygonObstacle: 0x14d20a60>",
    "<GKPolygonObstacle: 0x14d208b0>",
    "<GKPolygonObstacle: 0x14d207d0>",
    "<GKPolygonObstacle: 0x14d20a70>"
)

Каждый из которых был четко и соответствующим образом инициализирован и добавлен в сцену. Каждый из этих элементов фактически отвечает SpriteKitdidBeginContact:(SKPhysicsContact *)contact метод, поэтому кажется, что узлы правильно передают границы, которые они должны иметь.

Если кто-то знает, что я делаю неправильно, или лучший способ превратить каждый из этих "узлов препятствий" в GKObstacle Я был бы очень благодарен. Заранее спасибо!

ОБНОВЛЕНИЕ: Вот узел с физическим телом, которое я тестирую:

        SKSpriteNode *innerMap1 = [SKSpriteNode spriteNodeWithImageNamed:@"test"];
        innerMap1.physicsBody = [SKPhysicsBody bodyWithTexture:[SKTexture textureWithImageNamed:@"test"] size:CGSizeMake(innerMap1.frame.size.width*0.92, innerMap1.frame.size.height*0.92)];
        innerMap1.position = CGPointMake(-220, -140);
        innerMap1.physicsBody.dynamic = NO;

        [chapterSKSpriteNodes addObject:innerMap1];

Вот как выглядит тело skView.showsPhysics = YES;:

Итак, я знаю, что физическое тело - это то, что мне нужно. Когда я пытаюсь создать GKObstacle однако из этого тела он, похоже, не регистрируется как препятствие при назначении в целях избежания препятствий.

1 ответ

Это звучит как ошибка. Вы должны проверить массив возвращаемых данных с объектами препятствий из-за препятствий-объектов-физических объектов и убедиться, что вы на самом деле возвращаете ожидаемые препятствия. Я подозреваю, что нет.

Вы можете проверить соответствующие вершины на ваших препятствиях как таковые:

https://developer.apple.com/library/ios/documentation/GameplayKit/Reference/GKPolygonObstacle_Class/index.html

Убедитесь, что они соответствуют вашим ожиданиям.

Другие вопросы по тегам