SKNode sigue otro SKNode dentro de los límites SKConstraint

Estoy intentando simular un ojo con SpriteKit.

La pustack del ojo rastrea el dedo de los usuarios mientras se mueve por la pantalla, pero debe permanecer dentro de los límites del ojo.

Intenté resolver esto sin éxito con el uso de SKConstraint.

Editar

Mi pensamiento fue aplicar SKConstraints contra la pustack para restringir sus límites a la vista. Cualquier toque (es decir, toquesMovido (), etc.) se aplicará a la pustack en la forma de SKAction.moveTo () y SpriteKit se encarga de mantener la pustack dentro del límite del ojo.

let touchPoint = CGPoint() SKAction.moveTo( touchPoint, duration: 2) 

El código para el video está disponible: https://gist.github.com/anonymous/f2356e07d1ac0e67c25b1940662d72cb

Demo de video del globo ocular

Una image vale mas que mil palabras…

Imagina que la pustack es el círculo pequeño y blanco lleno. El cuadro azul simula que un usuario mueve su dedo por la pantalla.

Idealmente, la pustack sigue el recuadro azul alnetworkingedor de la pantalla y sigue el path definido por el círculo amarillo.

iOS 10 | Swift 3 | Xcode 8

En lugar de restringir por la distancia, puede usar una restricción de orientación para rotar un nodo y mirar hacia la location táctil. Al agregar el nodo "pustack" con un desplazamiento x al nodo que está restringido, la pustack se moverá hacia el punto de contacto. Aquí hay un ejemplo de cómo hacerlo:

 let follow = SKSpriteNode(color:.blue, size:CGSize(width:10,height:10)) let pupil = SKShapeNode(circleOfRadius: 10) let container = SKNode() let maxDistance:CGFloat = 25 override func didMove(to view: SKView) { addChild(container) // Add the pupil at an offset pupil.position = CGPoint(x: maxDistance, y: 0) container.addChild(pupil) // Node that shows the touch point addChild(follow) // Add an orientation constraint to the container let range = SKRange(constantValue: 0) let constraint = SKConstraint.orient(to: follow, offset: range) container.constraints = [constraint] } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { for t in touches { let location = t.location(in: self) follow.position = location adjustPupil(location: location) } } override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { for t in touches { let location = t.location(in: self) follow.position = location adjustPupil(location: location) } } // Adjust the position of the pupil within the iris func adjustPupil(location:CGPoint) { let dx = location.x - container.position.x let dy = location.y - container.position.y let distance = sqrt(dx*dx + dy*dy) let x = min(distance, maxDistance) pupil.position = CGPoint(x:x, y:0) } 

introduzca la descripción de la imagen aquí

Quería esperar una respuesta antes de que publique una respuesta, pero @ 0x141E y yo debatimos acerca de cómo funcionan las restricciones, así que aquí está el código. Úselo para saber dónde va mal.

 import SpriteKit class GameScene: SKScene { static let pupilRadius : CGFloat = 30 static let eyeRadius : CGFloat = 100 let follow = SKSpriteNode(color:.blue, size:CGSize(width:10,height:10)) let pupil = SKShapeNode(circleOfRadius: pupilRadius) override func didMove(to view: SKView) { let eye = SKShapeNode(circleOfRadius: GameScene.eyeRadius) eye.strokeColor = .white eye.fillColor = .white addChild(eye) pupil.position = CGPoint(x: 0, y: 0) pupil.fillColor = .blue eye.addChild(pupil) addChild(follow) pupil.constraints = [SKConstraint.distance(SKRange(lowerLimit: 0, upperLimit: GameScene.eyeRadius-GameScene.pupilRadius), to: eye)] } func moveFollowerAndPupil(_ location:CGPoint){ follow.position = location pupil.position = convert(location, to: pupil.parent!) } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { touches.forEach({moveFollowerAndPupil($0.location(in: self))}) } override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { touches.forEach({moveFollowerAndPupil($0.location(in: self))}) } } 

Como puede ver, no uso la raíz cuadrada en mi extremo, es de esperar que Apple sea lo suficientemente inteligente como para no usarlo ya que no es necesario, lo que significa que, en teoría, debería ser más rápido que hacer manualmente la fórmula de distancia.

introduzca la descripción de la imagen aquí