问题描述
我对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子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!