GameplayKit

时间:2016-07-25 14:56:23

标签: ios objective-c sprite-kit gameplay-kit

这是我的问题:

  • 如何将SKSpriteNode数组转换为GKObstacles数组,以便代理可以使用goalToAvoidObstacles:(nonnull NSArray<GKObstacle *> *) maxPredictionTime:(NSTimeInterval) /?<正确避免这些障碍/ LI>

似乎我创建GKObstacle数组的方式不允许GKGoal正确识别这些障碍,无论我给目标赋予什么样的重量。

我目前有几个SKNode已添加到SKScene chapterScene 。这些节点中的每一个都被添加到我正在存储的名为 impedArray 的数组中。我已经按照以下方式设置了一个测试非常好的测试:

工作障碍

- (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 body数组作为障碍。我只能将这些手动创建的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方法进行响应,因此似乎节点正确地处理它们应该具有的边界。

如果有人知道我做错了什么或者更好的方法来解决这些障碍节点的问题&#39;进入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;的正文:

enter image description here

所以我知道物理机构就是我所需要的。然而,当我尝试从这个身体创建GKObstacle时,它似乎在被指定为avoidObstacles目标时被注册为障碍。

1 个答案:

答案 0 :(得分:0)

这听起来像个错误。你应该检查来自barriersFromNodePhysicsBodies的返回数组,并确保你实际上找回了你期望的障碍。我怀疑你不是。

您可以检查障碍物上的相关顶点:

https://developer.apple.com/library/ios/documentation/GameplayKit/Reference/GKPolygonObstacle_Class/index.html#//apple_ref/occ/cl/GKPolygonObstacle

确保它们符合您的期望。