`-costToNode:` 未发送到 GameplayKit 中的 GKGraphNode2D 子类
`-costToNode:` Not Sent to GKGraphNode2D Subclass in GameplayKit
关于 Apple 的新 GameplayKit,我有一个也许是愚蠢的问题。
我正在为我的游戏创建基于二维网格的节点布局。我最喜欢 GKGraphNode2D
的功能,但想以一种方式对其进行调整。我想在遍历某种节点对时有条件地添加惩罚。换句话说,我希望一些节点以直接的方式连接,而一些节点连接使得它们的遍历距离被我的应用程序修改。
我认为子类化 GKGraphNode2D
并覆盖 -costToNode:
和 -estimatedCostToNode:
会很完美!有时我会 return super
提供的值,并在其他时候为我的游戏调整它。这两个方法是 GKGraphNode
上的方法,GKGraphdNode2D
.
的超类
不幸的是,当我尝试这样做时,-costToNode:
和 -estimatedCostToNode:
似乎从未在我的 GKGraphNode2D
子类上被调用。当我在包含一堆 GKGraphNode2D
子类对象的 GKGraph
对象上调用 -findPathFromNode:toNode:
时,我希望这些方法被调用。
我做错了什么?
编辑:
以下是我的代码。
创建两个类、CheapNode
和ExpensiveNode
,它们是GKGraphNode2D
的sub类,如下:
@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:
消息发送到图形。然后,我检查图表找到的路径,但没有找到我期望的。
- (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
sub类(由日志语句和断点验证)。
Here 是演示此问题的示例项目。它应该构建 运行 Xcode 的最新开发人员测试版(截至 08/31/2015,Xcode beta 6)。
编辑 2:
如果有人对复制感兴趣,我已将此 Whosebug 问题中的示例代码和描述作为错误 (http://www.openradar.me/22524760) 提交。如果 iOS 9 发布后错误仍然存在,我将使用开发人员支持票尝试解决此问题。
编辑 3:
Apple 通过我的开发者支持票回复了我。他们承认这是一个错误,并且它(据我所知)似乎已在 iOS 9.2 beta 2 (7C46t) 中修复。
编辑 4:
我已经用这个框架更新了 sample project to illustrate another 。
Apple 回复了我与此问题相关的开发人员支持票,并告诉我这是一个已知问题,并且在 2015 年 11 月 3 日发布的 iOS SDK 9.2 beta 2 中有一个潜在的修复。我验证了我的 test project 中的测试在 9.2b2 中通过了,所以我希望该版本能够解决这个问题。
关于 Apple 的新 GameplayKit,我有一个也许是愚蠢的问题。
我正在为我的游戏创建基于二维网格的节点布局。我最喜欢 GKGraphNode2D
的功能,但想以一种方式对其进行调整。我想在遍历某种节点对时有条件地添加惩罚。换句话说,我希望一些节点以直接的方式连接,而一些节点连接使得它们的遍历距离被我的应用程序修改。
我认为子类化 GKGraphNode2D
并覆盖 -costToNode:
和 -estimatedCostToNode:
会很完美!有时我会 return super
提供的值,并在其他时候为我的游戏调整它。这两个方法是 GKGraphNode
上的方法,GKGraphdNode2D
.
不幸的是,当我尝试这样做时,-costToNode:
和 -estimatedCostToNode:
似乎从未在我的 GKGraphNode2D
子类上被调用。当我在包含一堆 GKGraphNode2D
子类对象的 GKGraph
对象上调用 -findPathFromNode:toNode:
时,我希望这些方法被调用。
我做错了什么?
编辑:
以下是我的代码。
创建两个类、CheapNode
和ExpensiveNode
,它们是GKGraphNode2D
的sub类,如下:
@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:
消息发送到图形。然后,我检查图表找到的路径,但没有找到我期望的。
- (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
sub类(由日志语句和断点验证)。
Here 是演示此问题的示例项目。它应该构建 运行 Xcode 的最新开发人员测试版(截至 08/31/2015,Xcode beta 6)。
编辑 2:
如果有人对复制感兴趣,我已将此 Whosebug 问题中的示例代码和描述作为错误 (http://www.openradar.me/22524760) 提交。如果 iOS 9 发布后错误仍然存在,我将使用开发人员支持票尝试解决此问题。
编辑 3:
Apple 通过我的开发者支持票回复了我。他们承认这是一个错误,并且它(据我所知)似乎已在 iOS 9.2 beta 2 (7C46t) 中修复。
编辑 4:
我已经用这个框架更新了 sample project to illustrate another
Apple 回复了我与此问题相关的开发人员支持票,并告诉我这是一个已知问题,并且在 2015 年 11 月 3 日发布的 iOS SDK 9.2 beta 2 中有一个潜在的修复。我验证了我的 test project 中的测试在 9.2b2 中通过了,所以我希望该版本能够解决这个问题。