Препятствия с 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>"
)
Каждый из которых был четко и соответствующим образом инициализирован и добавлен в сцену. Каждый из этих элементов фактически отвечает SpriteKit
didBeginContact:(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 ответ
Это звучит как ошибка. Вы должны проверить массив возвращаемых данных с объектами препятствий из-за препятствий-объектов-физических объектов и убедиться, что вы на самом деле возвращаете ожидаемые препятствия. Я подозреваю, что нет.
Вы можете проверить соответствующие вершины на ваших препятствиях как таковые:
Убедитесь, что они соответствуют вашим ожиданиям.