这是我的问题:
- 如何将
SKSpriteNode
数组转换为数组,GKObstacles
以便代理可以使用/ 适当地避开goalToAvoidObstacles:(nonnull NSArray<GKObstacle *> *) maxPredictionTime:(NSTimeInterval)
这些障碍?
似乎我创建GKObstacle
数组的方式不允许GKGoal
正确地将这些识别为障碍,无论我给目标赋予什么权重。
我目前有几个SKNode
s 添加到SKScene
chapterScene中。这些节点中的每一个都被添加到我正在存储的名为barrierArray的数组中。我已经通过以下方式设置了一个运行良好的测试:
工作障碍
- (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
's,我将不胜感激。提前致谢!
更新:这是一个我正在测试的带有物理主体的节点:
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
从该主体创建时,在避免障碍目标中分配时,它似乎没有注册为障碍。