我对Apple的新GameplayKit有一个愚蠢的问题.
我正在为我的游戏创建一个基于2D网格的节点布局.我大多喜欢它的功能GKGraphNode2D,但想以一种方式调整它.我想在遍历某种节点对时有条件地添加惩罚.换句话说,我希望一些节点以直接的方式连接,并且一些节点连接起来使得它们的遍历距离被我的app修改.
我认为继承GKGraphNode2D和覆盖-costToNode:,-estimatedCostToNode:并将完美地工作!我super有时会返回提供的值,并在其他时间为我的游戏调整它.这两个方法都是方法GKGraphNode,超类GKGraphdNode2D.
不幸的是,当我尝试这样做时,似乎-costToNode:并且-estimatedCostToNode:永远不会在我的GKGraphNode2D子类上调用它.我希望当我打电话要调用这些方法-findPathFromNode:toNode:我的GKGraph对象,它包含了一堆我的GKGraphNode2D子类的对象.
我究竟做错了什么?
以下是我的代码.
创建两个班,CheapNode和ExpensiveNode,是的子类GKGraphNode2D,如下所示:
@import UIKit;
@import GameplayKit;
@interface CheapNode : GKGraphNode2D
@end
@implementation CheapNode
- (float)estimatedCostToNode:(GKGraphNode *)node {
return 1;
}
- (float)costToNode:(GKGraphNode *)node {
return 1;
}
@end
Run Code Online (Sandbox Code Playgroud)
和
@import UIKit;
@import GameplayKit;
@interface ExpensiveNode : GKGraphNode2D
@end
@implementation ExpensiveNode
- (float)estimatedCostToNode:(GKGraphNode *)node {
return 100;
}
- (float)costToNode:(GKGraphNode *)node {
return 100;
}
@end
Run Code Online (Sandbox Code Playgroud)
然后在测试中,我创建了一些节点,连接它们,将它们添加到图形中,然后将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], @"");
}
Run Code Online (Sandbox Code Playgroud)
此测试用例失败.我也注意到estimatedCostToNode:并且costToNode:从未发送到我的GKGraphNode2D子类(由日志语句和断点验证).
这是一个展示此问题的示例项目.它应该构建并运行Xcode的最新开发者测试版(截至2015年8月31日,Xcode beta 6).
如果有人对重复感兴趣,我已将此StackOverflow问题中的示例代码和说明作为错误提交(http://www.openradar.me/22524760).如果在iOS 9发布后错误仍然存在,我将使用开发人员支持服务单来尝试解决此问题.
Apple在我的开发者支持服务单上回复了我.他们承认这是一个错误,它(据我所知)似乎在iOS 9.2 beta 2(7C46t)中得到修复.
| 归档时间: |
|
| 查看次数: |
380 次 |
| 最近记录: |