web-dev-qa-db-fra.com

SKNode convertPoint toNode & fromNode confusion?

Je suis un peu confus par la façon dont fonctionnent les méthodes SKNode, convertPoint:fromNode: et convertPoint:ToNode:. J'ai examiné la documentation, mais ce n'est pas évident. Par exemple, ceci ( voir diagramme ci-dessous ) est un petit test que j’ai fait avec convertPoint:fromNode:. La zone noire correspond à l’arrière-plan SKScene, la zone bleue est une SKSpriteNode associée à la SKScene, la zone rouge correspond à une autre SKSpriteNode associée à la bleue. Lutin. Les points d'ancrage des deux sprites sont indiqués par les petits points verts. Ce que je voulais faire, c’était obtenir la position de la scène pour le Sprite rouge, ce que j’ai fait en utilisant le code suivant:

CGPoint positionInScene = [self convertPoint:[self position] 
                                    fromNode:[self redSprite]];

Le résultat de ceci est

positionInScene = [105, 205]

C'est ce à quoi je m'attendais, car ce serait l'Origine du carré rouge dans l'espace de la scène. Ce qui me rend confus, ce sont les arguments. De ce que je peux deviner:

[SKNode_A convertPoint: CGPoint_B toNode: SKScene_C]
  • SKNode_A = L'espace de coordonnées du noeud à convertir en ...
  • CGPoint_B = Le point à convertir (vous ne savez pas pourquoi sa [position auto] ci-dessus)
  • SKNode_C = L'espace de coordonnées du noeud à partir duquel convertir.

Mon essai initial était [self convertPoint:[redSprite position] fromNode:redSprite] parce que je voulais convertir les sprites rouges Origin en scène. Cela semble un peu gênant de faire le tour de la tête. Si quelqu'un peut jeter un peu de lumière et de logique sur ceci et sur son ami, convertPoint:toNode:, ce serait très apprécié.

enter image description here

34
fuzzygoat

- (CGPoint) convertPoint: (CGPoint) point fromNode: (SKNode *) node

Ceci dit essentiellement: convertissez un point exprimé dans le système de coordonnées d'un autre noeud en un système de coordonnées (self) de l'appelant. La clé est que le point doit être exprimé dans le système de coordonnées du nœud pour que cela fonctionne. Si vous utilisez la position d'un sprite comme point, vous devrez passer le nœud parent du sprite comme dernier argument.

Exemple: Pour obtenir la position du carré rouge dans le système de coordonnées de la scène:

CGPoint positionInScene = [self convertPoint:[redSprite position]
                                    fromNode:[self blueSprite]];

[5, 5] dans le système de coordonnées de blueSprite -> [105, 205] dans le système de coordonnées de la scène

Votre exemple:  

CGPoint positionInScene = [self convertPoint:[self position] 
                                    fromNode:[self redSprite]];

[0, 0] dans le système de coordonnées de RedSprite -> [105, 205] dans le système de coordonnées de la scène

Vous avez fini avec le même résultat de votre code, uniquement parce que [self position] était [0, 0] et que vous utilisiez le système de coordonnées de RedSprite. Votre tentative initiale était proche, il vous suffisait de fournir le système de coordonnées dans lequel la position de redSprite était exprimée, à savoir le système de coordonnées du sprite parent; dans ce cas, c'est blueSprite.

- (CGPoint) convertPoint: (CGPoint) pointe sur un nœud: nœud (SKNode *)

Cette méthode est à l’opposé de la première méthode. Il convertira un point dans le système de coordonnées de l'appelant en un autre système de coordonnées node. La clé de cette méthode est que le point donné doit être exprimé dans le système de coordonnées de l'appelant.

Exemple: Supposons que votre scène a reçu une touche tactile sur [125, 225] et que vous vouliez ajouter un nouveau Sprite à cet emplacement, qui se trouve dans le cadre de redSprite. Donc, pour ajouter un nouveau Sprite en tant qu'enfant de redSprite, vous devez obtenir l'emplacement du contact dans le système de coordonnées de redSprite. Pour l'obtenir:

CGPoint positionInRedSprite = [self convertPoint:touchLocation 
                                          toNode:[self redSprite]];

[125, 225] dans le système de coordonnées de la scène -> [20, 20] dans le système de coordonnées de RedSprite

47
kevin.

Je sais que la réponse est tardive, mais normalement, je souhaite utiliser le parent du nœud comme système de coordonnées pour la position du nœud. J'ai donc trouvé cette extension très utile:

extension SCNNode {
    func convertPosition(node:SCNNode) -> SCNVector3 {
        return self.convertPosition(node.position, fromNode:node.parentNode)
    }
}

Par exemple, au lieu d'appeler ceci:

let position = scene.rootNode.convertPosition(node.position, fromNode: node.parentNode)

vous appelez juste ceci:

let position = scene.rootNode.convertPosition(node)
0
Brainware

Pour plus de simplicité: Lorsque vous comparez l’emplacement du nœud B avec le nœud A (essayez de déterminer la distance qui les sépare)

var BInSameCoordinateSys = NodeA.parent!.convertPoint(NodeB.position, fromNode: NodeB.parent!)

Résoudre les problèmes en ajoutant un Sprite à l'emplacement si cela ne fonctionne pas pour aider à visualiser l'emplacement:

let childToSeeLocation = SKShapeNode(CircleWithRadius:50)
childToSeeLocation.fillColor = UIColor.redColor
ParentofA.addChild(childToSeeLocation)
0
eric bob

Après avoir lu l'excellente réponse de kevin., J'ai pu faire quelques extensions de SKNode qui sont à la fois un excellent exemple et un ensemble d'outils très pratique. 

extension SKNode {

var frameInScene:CGRect {
    get {
        if let scene = self.scene {
            if let parent = self.parent {
                let rectOriginInScene = scene.convertPoint(self.frame.Origin, fromNode: parent)
                return CGRect(Origin: rectOriginInScene, size: self.frame.size)
            }
        }
        println("Just the normal frame, not the scene frame!!!")
        return frame
    }
}

var positionInScene:CGPoint {
    get {
        if let scene = self.scene {
            if let parent = self.parent {
                return scene.convertPoint(self.position, fromNode: parent)
            }
        }
        println("Just the normal position, not the scene position!!!")
        return position
    }
}
}

Je pense que vous pourriez probablement supprimer chaque self., mais j’ai pensé que cela rendait le code plus confus. Et je ne suis pas tout à fait sûr de savoir quoi faire si le nœud n'appartient à aucune scène ni à aucun nœud parent. Je viens donc de retourner le cadre et la position normaux et d'utiliser une fonction println() pour me donner un avertissement.

Si quelqu'un a des modifications/ajouts à ce code, j'aimerais l'entendre, surtout si cela aide à répondre à la question davantage.

0
mogelbuster