2014-03-28 6 views
5

Gibt es eine Möglichkeit, die nächsten Knoten zu einem Knoten zu bekommen?SpriteKit - nächstgelegene Knoten

Ich bin gerade dabei, eine Methode zu schreiben, um alle Knoten zu iterieren und Distanzen usw. zu berechnen ... aber fragte mich, ob es einen besseren Weg gibt?

Ich habe 30 Knoten und brauche die 2 nächsten Knoten zu jedem der 30 Knoten (wenn das Sinn macht).

+5

Ich weiß nicht, ob SpriteKit eine vorgefertigte Methode hat, dies zu tun. Als eine allgemeine Algorithmusfrage übersteigt der Aufwand, der mit der Optimierung der Suche verbunden ist, die Vorteile, es sei denn, Sie haben 100 Knoten. Als eine Randnotiz frage ich mich, ob Sie in Betracht gezogen haben, dass die Ergebnisse der Suche nach den zwei nächsten Knoten keine Symmetrie haben. Mit anderen Worten, wenn B und C die zwei nächsten Knoten zu A sind, bedeutet dies nicht notwendigerweise, dass A einer der zwei nächsten Knoten zu B ist. – user3386109

+0

Ja, ich hatte bereits an den Mangel an Symmetrie gedacht. Am Ende habe ich es getan, indem ich das Array von Knoten sortiert (nach Entfernung zu einem bestimmten Knoten) und das Sub-Array der benötigten Größe zurückgegeben habe. Wahrscheinlich nicht so effizient, aber ich experimentiere ... und es ist 1 Uhr morgens. : D – Fogmeister

+3

eine Optimierungsstrategie heißt räumliche Partitionierung, aber wie oben gesagt, ist es wahrscheinlich Overkill ohne Hunderte von Knoten – LearnCocos2D

Antwort

2

Ab iOS 10 können Sie die Funktionen zur räumlichen Partitionierung von GampelayKit verwenden. In 2D entweder GKQuadtree oder GKRTree je nach Ihren Bedürfnissen.

Aus der Dokumentation:

Quadtrees und R-Bäume haben unterschiedliche Performance Kompromissen für unterschiedliche Aufgaben: Quadtrees kann schneller sein, wenn Objekte mehr gleichmäßig im Raum verteilt oder wenn ihre Positionen ändern sich häufig, und R-Bäume kann bei der Suche nach allen Objekten in einer bestimmten Region schneller sein.

Ihre Feinde zu dem Baum hinzufügen:

let minX = Float(enemy.frame.minX) 
    let minY = Float(enemy.frame.minY) 
    let maxX = Float(enemy.frame.maxX) 
    let maxY = Float(enemy.frame.maxY) 

    var enemiesRTree = GKRTree(maxNumberOfChildren: 3) 
    enemiesRTree.addElement(enemy, 
          boundingRectMin: vector2(minX, minY), 
          boundingRectMax: vector2(maxX, maxY), 
          splitStrategy: GKRTreeSplitStrategy.linear) 

Dann können Sie nach Gebiet suchen.

let enemiesInProximity = enemiesRTree.elements(
     inBoundingRectMin: vector2(0, 0), 
     rectMax: vector2(100, 100)) 

Sie können dann den Suchbereich z. relativ zur Position des Spielers.

1

Ich glaube, dass Ihr Ansatz für diese Situation am besten geeignet ist. Wenn Sie alle Knoten in einem Array-Stil gespeichert haben, kann es eine relativ effiziente Möglichkeit geben, das zu tun, was Sie oben erwähnt haben.

In jeder Situation können Sie immer noch damit beauftragt werden, drei Knoten am nächsten zu haben. Wenn dies kein Problem ist, verwenden Sie eine Methode, die eine Knotenposition annimmt und dann mit der for-Schleife "unsichtbare Kreise" mit zunehmendem Radius projiziert, bis ein Kreis schließlich genau 2 Knoten enthält. Dann gib einfach diese Knoten zurück.

Verwandte Themen