ios7 sprite-kit sknode

ios7 - ¿La confusión de SKNode convertPoint toNode y fromNode?



sprite-kit (4)

- (CGPoint) convertPoint: (CGPoint) punto fromNode: (SKNode *) nodo

Esto esencialmente dice: convertir un punto expresado en el sistema de coordenadas de otro nodo en el sistema de coordenadas ( auto ) de la persona que llama. La clave es que el punto debe expresarse en el sistema de coordenadas del nodo para que esto funcione. Si está utilizando la posición de un sprite como punto, tendrá que pasar el nodo padre del sprite como último argumento.

Ejemplo: Para obtener la posición del cuadrado rojo en el sistema de coordenadas de la escena:

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

[5, 5] en el sistema de coordenadas de BlueSprite -> [105, 205] en el sistema de coordenadas de la escena

Tu ejemplo:

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

[0, 0] en el sistema de coordenadas de redSprite -> [105, 205] en el sistema de coordenadas de la escena

Terminaste con el mismo resultado de tu código, solo porque [self position] era [0, 0] y usaste el sistema de coordenadas de redSprite. Tu intento inicial estuvo cerca, solo necesitas proporcionar el sistema de coordenadas en el que se expresó la posición de redSprite, que es el sistema de coordenadas del sprite padre; en este caso, eso es blueSprite.

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

Este método es muy opuesto al primer método. Convertirá un punto en el sistema de coordenadas del llamante en el sistema de coordenadas de otro nodo . La clave para este método es que el punto dado debe expresarse en el sistema de coordenadas de la persona que llama.

Ejemplo: Supongamos que su escena recibió un toque en [125, 225] , y que desea agregar un nuevo elemento en esa ubicación, que se encuentra dentro del cuadro delimitador de redSprite. Por lo tanto, para agregar un nuevo sprite como elemento secundario de redSprite, debe obtener la ubicación del toque en el sistema de coordenadas de redSprite. Para obtener eso:

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

[125, 225] en el sistema de coordenadas de la escena -> [20, 20] en el sistema de coordenadas de redSprite

Estoy un poco confundido por cómo los métodos convertPoint:fromNode: y convertPoint:ToNode: están funcionando, he examinado los documentos, pero no es tan obvio lo que hacen. Por ejemplo, esto ( ver el diagrama a continuación ) es una pequeña prueba que hice usando convertPoint:fromNode: el área negra es el fondo SKScene , el área azul es un SKSpriteNode emparentado con el SKScene , el área roja es otro SKSpriteNode emparentado con el sprite azul . Los puntos de anclaje para ambos sprites se muestran con pequeños puntos verdes. Lo que quería hacer era obtener la posición de escena para el sprite rojo, lo cual hice usando el siguiente código:

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

El resultado de esto es

positionInScene = [105, 205]

Que es lo que esperaba, ya que ese sería el origen del cuadrado rojo en el espacio de la escena. Lo que me confunde son los argumentos. Por lo que puedo adivinar:

[SKNode_A convertPoint: CGPoint_B toNode: SKScene_C]

  • SKNode_A = El espacio de coordenadas del nodo para convertir a ...
  • CGPoint_B = El punto a convertir (no estoy seguro de por qué su [posición propia] arriba)
  • SKNode_C = El espacio de coordenadas del nodo para convertir de ...

Mi primer intento en esto fue [self convertPoint:[redSprite position] fromNode:redSprite] porque quería convertir el origen de los sprites rojos a la escena. Simplemente parece un poco torpe darse la vuelta, si alguien puede arrojar un poco de luz y lógica sobre este y su amigo convertPoint:toNode: sería muy apreciado.


Después de leer la gran respuesta de Kevin, pude hacer algunas extensiones de SKNode que son un gran ejemplo y un útil conjunto de herramientas.

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 } } }

Creo que probablemente puedas borrar cada self. pero sentí que hace que el código sea más confuso. Y no estoy del todo seguro de qué hacer si el nodo no pertenece a ninguna escena o nodo padre, así que simplemente println() el marco y la posición normales y usé println() para darme una advertencia.

Si alguien tiene cambios / adiciones a este código, me encantaría escucharlo, especialmente si ayuda a responder la pregunta aún más.


Por simplicidad: cuando se compara la ubicación del nodo B con el nodo A (tratando de encontrar qué tan lejos están el uno del otro)

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

Solucione problemas agregando un sprite en la ubicación si no está trabajando para ayudar a visualizar la ubicación:

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


Sé que esta es una respuesta tardía, pero normalmente, quiero usar el padre del nodo como el sistema de coordenadas para la posición del nodo. Entonces, encontré que esta extensión es muy útil:

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

Por ejemplo, en lugar de llamar esto:

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

simplemente llama esto:

let position = scene.rootNode.convertPosition(node)