本文介绍了`-costToNode:`没有发送到GameplayKit中的GKGraphNode2D子类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Apple的新GameplayKit有一个愚蠢的问题。

I have what is perhaps a stupid question about Apple's new GameplayKit.

我正在为我的游戏创建一个基于2D网格的节点布局。我主要喜欢 GKGraphNode2D 的功能,但想以一种方式调整它。我想在遍历某种节点对时有条件地添加惩罚。换句话说,我希望一些节点以直接方式连接,并且一些节点连接使得它们的遍历距离被我的应用程序修改。

I am creating a 2D grid-based node layout for my game. I mostly love the functionality of the GKGraphNode2D, but would like to tweak it in one way. I'd like to conditionally add a penalty when traversing a certain kind of node pair. In other words, I want some nodes connected in a straight-forward way, and some nodes connected such that their traversal distance is modified by my app.

我认为子类化 GKGraphNode2D 并覆盖 -costToNode: -estimatedCostToNode:可以正常工作完美!我有时会返回 super 提供的值,并在其他时间为我的游戏调整它。这两种方法是 GKGraphNode 上的方法, GKGraphdNode2D 的超类。

I thought subclassing GKGraphNode2D and overriding -costToNode: and -estimatedCostToNode: would work perfectly! I'd return the value supplied by super sometimes, and tweak it for my game at other times. These two methods are methods on GKGraphNode, the superclass of GKGraphdNode2D.

不幸的是,当我尝试这样做时,似乎 -costToNode: -estimatedCostToNode:是从未调用过我的 GKGraphNode2D 子类。当我在包含一堆的 GKGraph 对象上调用 -findPathFromNode:toNode:时,我希望调用这些方法我的 GKGraphNode2D 子类对象。

Unfortunately, when I try to do this, it appears that -costToNode: and -estimatedCostToNode: are never called on my GKGraphNode2D subclass. I would expect these methods to be invoked when I call -findPathFromNode:toNode: on my GKGraph object that contains a bunch of my GKGraphNode2D subclass objects.

我做错了什么?

以下是我的代码。

创建两个类, CheapNode ExpensiveNode ,它们是 GKGraphNode2D 的子类,如下所示:

Create two classes, CheapNode and ExpensiveNode, that are subclasses of GKGraphNode2D, as follows:

@import UIKit;
@import GameplayKit;

@interface CheapNode : GKGraphNode2D
@end

@implementation CheapNode

- (float)estimatedCostToNode:(GKGraphNode *)node {
    return 1;
}

- (float)costToNode:(GKGraphNode *)node {
    return 1;
}

@end

@import UIKit;
@import GameplayKit;

@interface ExpensiveNode : GKGraphNode2D
@end

@implementation ExpensiveNode

- (float)estimatedCostToNode:(GKGraphNode *)node {
    return 100;
}

- (float)costToNode:(GKGraphNode *)node {
    return 100;
}

@end

然后在测试中,我已经创建了一些节点,连接它们,将它们添加到图形中,并将 findPathFromNode:toNode:消息发送到图形。然后,我检查图表找到的路径,我找不到我期望的。

Then in a test, I've created some nodes, connected them, added them to a graph, and sent the findPathFromNode:toNode: message to the graph. Then, I check the path that the graph finds, and I don't find what I expect.

- (void)testNodeCostsUsed {
    /*
     This is the graph we are creating:

     A---B---C
     |       |
     F---E---D

     where all of the nodes are `CheapNode` objects, except 'B', which is an
     `ExpensiveNode` object.

     This test finds a path from node A to node C.

     If the cost methods in the `CheapNode` and `ExpensiveNode` subclasses
     are used, the route going from A to C around B (down, then right, then up)
     should be used, since the cost of going from B to C is 100, and the cost of
     going from any other node to any other node is 1
     (see implementation of these classes).

     Instead, we see `GKGraph` choosing the "shortest" route in terms of number
     of nodes, from the top left immediately to the right to the top right.
     */

    CheapNode     *nodeA = [[CheapNode alloc]     initWithPoint:(vector_float2){0, 0}];
    ExpensiveNode *nodeB = [[ExpensiveNode alloc] initWithPoint:(vector_float2){1, 0}];
    CheapNode     *nodeC = [[CheapNode alloc]     initWithPoint:(vector_float2){2, 0}];
    CheapNode     *nodeD = [[CheapNode alloc]     initWithPoint:(vector_float2){2, 1}];
    CheapNode     *nodeE = [[CheapNode alloc]     initWithPoint:(vector_float2){1, 1}];
    CheapNode     *nodeF = [[CheapNode alloc]     initWithPoint:(vector_float2){0, 1}];

    [nodeA addConnectionsToNodes:@[ nodeB, nodeF ] bidirectional:YES];
    [nodeC addConnectionsToNodes:@[ nodeB, nodeD ] bidirectional:YES];
    [nodeE addConnectionsToNodes:@[ nodeF, nodeD ] bidirectional:YES];

    NSArray *allNodes = @[ nodeA, nodeB, nodeC, nodeD, nodeE, nodeF ];

    GKGraph *graph = [GKGraph graphWithNodes:allNodes];
    NSArray *nodes = [graph findPathFromNode:nodeA toNode:nodeC];

    NSArray *expectedPath   = @[ nodeA, nodeF, nodeE, nodeD, nodeC ];
    NSArray *prohibitedPath = @[ nodeA, nodeB, nodeC ];

    XCTAssert([nodes isEqualToArray:expectedPath], @"");
    XCTAssertFalse([nodes isEqualToArray:prohibitedPath], @"");
}

此测试用例失败。我还注意到 estimatedCostToNode: costToNode:永远不会发送到我的 GKGraphNode2D 子类(由日志语句和断点验证)。

This test case fails. I also notice that estimatedCostToNode: and costToNode: are never sent to my GKGraphNode2D subclasses (as verified by log statements and breakpoints).

是一个展示此问题的示例项目。它应该构建并运行Xcode的最新开发者测试版(截至2015年8月31日,Xcode beta 6)。

Here is a sample project demonstrating this issue. It should build and run on the latest developer beta of Xcode (as of 08/31/2015, Xcode beta 6).

我已将此StackOverflow问题中的示例代码和说明作为错误提交()如果有人对复制感兴趣。如果在iOS 9发布后错误仍然存​​在,我将使用开发人员支持服务单来尝试解决此问题。

I have submitted the sample code and the description in this StackOverflow question as a bug (http://www.openradar.me/22524760) if anyone is interested in duping. If the bug persists after iOS 9 is released, I will use a developer support ticket to try to resolve this issue.

这篇关于`-costToNode:`没有发送到GameplayKit中的GKGraphNode2D子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-14 10:26