`-costToNode:` Не отправлено в подкласс GKGraphNode2D в GameplayKit

У меня, возможно, глупый вопрос о новом GameplayKit от Apple.

Я создаю 2D-макет на основе сетки для моей игры. Я в основном люблю функциональность GKGraphNode2D, но хотел бы настроить его одним способом. Я хотел бы условно добавить штраф при обходе определенного типа пары узлов. Другими словами, я хочу, чтобы некоторые узлы были подключены прямым способом, а некоторые узлы были подключены так, чтобы расстояние их прохождения изменялось моим приложением.

Я думал, что подкласс 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

а также

@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 подклассы (как проверено лог-операторами и точками останова).

Вот пример проекта, демонстрирующего эту проблему. Он должен собираться и работать на последней бета-версии Xcode для разработчиков (по состоянию на 31.08.2015, бета-версия Xcode 6).

Изменить 2:

Я отправил образец кода и описание в этом вопросе Stackru как ошибку ( http://www.openradar.me/22524760), если кто-то заинтересован в дублировании. Если ошибка не исчезнет после выхода iOS 9, я воспользуюсь билетом поддержки разработчиков, чтобы попытаться решить эту проблему.

Изменить 3:

Apple вернулась ко мне в мой билет поддержки разработчиков. Они признали, что это ошибка, и она (насколько я могу судить), похоже, исправлена ​​в iOS 9.2 beta 2 (7C46t).

Изменить 4:

Я обновил пример проекта, чтобы проиллюстрировать еще одну ошибку с этим фреймворком.

1 ответ

Решение

Apple ответила на мою заявку в службу поддержки разработчиков, связанную с этой проблемой, и сказала, что это известная проблема, и что существует потенциальное исправление в iOS SDK 9.2 beta 2, выпущенной 3 ноября 2015 года. Я проверил, что тесты в моем тестовом проекте перейти к 9.2b2, и поэтому я ожидаю, что эта версия решит эту проблему.

Другие вопросы по тегам