以下是我的问题:
SKSpriteNode
数组转换为GKObstacles
数组,以便代理能够通过使用goalToAvoidObstacles:(nonnull NSArray<GKObstacle *> *) maxPredictionTime:(NSTimeInterval)
/适当地避免这些障碍?我创建GKObstacle
数组的方式似乎是不允许GKGoal
正确地将这些障碍识别为障碍,不管我对目标的权重有多大。
我现在有几个添加到chapterScene.中的SKNode
。这些节点中的每一个都添加到我要存储的称为obstaclesArray.的数组中。我以以下方式设置了一个测试,效果非常好:
工作障碍
- (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
,我会非常感激的。
UPDATE:下面是我正在测试的一个物理实体的节点:
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
时,它在被分配到avoidObstacles目标时似乎并不是一个障碍。
发布于 2016-08-03 00:50:02
这听起来像虫子。您应该检查来自obstaclesFromNodePhysicsBodies的返回数组,并确保您实际上正在返回您所期望的障碍。我怀疑你不是。
您可以检查与您的障碍相关的顶点:
确保他们是你所期望的。
https://stackoverflow.com/questions/38571104
复制相似问题