首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >GameplayKit障碍

GameplayKit障碍
EN

Stack Overflow用户
提问于 2016-07-25 14:56:22
回答 1查看 603关注 0票数 1

以下是我的问题:

  • 如何将SKSpriteNode数组转换为GKObstacles数组,以便代理能够通过使用goalToAvoidObstacles:(nonnull NSArray<GKObstacle *> *) maxPredictionTime:(NSTimeInterval)/适当地避免这些障碍?

我创建GKObstacle数组的方式似乎是不允许GKGoal正确地将这些障碍识别为障碍,不管我对目标的权重有多大。

我现在有几个添加到chapterScene.中的SKNode。这些节点中的每一个都添加到我要存储的称为obstaclesArray.的数组中。我以以下方式设置了一个测试,效果非常好:

工作障碍

代码语言:javascript
运行
复制
- (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的任何障碍:

非工作障碍

代码语言:javascript
运行
复制
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]];

不幸的是,这似乎不起作用,因为无论我有多高的权重,代理人从来没有回应回避的障碍。下面是我要传递给它的数组的日志:

代码语言:javascript
运行
复制
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:下面是我正在测试的一个物理实体的节点:

代码语言:javascript
运行
复制
        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目标时似乎并不是一个障碍。

EN

回答 1

Stack Overflow用户

发布于 2016-08-03 00:50:02

这听起来像虫子。您应该检查来自obstaclesFromNodePhysicsBodies的返回数组,并确保您实际上正在返回您所期望的障碍。我怀疑你不是。

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

ref/occ/cl/GKPolygonObstacle

确保他们是你所期望的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38571104

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档