ios sprite-kit physics skphysicsbody skphysicsjoint

ios - Junta SpriteKit: sigue el cuerpo



sprite-kit physics (1)

"Todas las piezas restantes de la serpiente deberían seguir la cabeza; deberían viajar exactamente en la misma dirección que la cabeza hace algún tiempo".

Debe tener en cuenta que con las articulaciones de Física es probable que tenga varianza, sin importar lo que haga. Incluso si lo tienes cerca de perfecto, tendrás errores de redondeo debajo del capó que hacen que el camino no sea exacto.

Si todas las partes de la cola son iguales, también puedes usar un enfoque diferente, esto es algo que he hecho para una cola de cometa. Básicamente, la idea es que tenga una matriz de objetos de cola y movimiento por cuadro mueva el último objeto de cola siempre a la misma posición que el objeto de cabeza. Si el objeto principal tiene una posición z más alta, la cola se dibuja debajo de él.

Si necesita mantener la cola en orden, puede variar el enfoque almacenando una matriz de posiciones de encabezado (ruta por cuadro) y luego colocar los objetos de cola a lo largo de esa ruta en su llamada de actualización por cuadro a la serpiente.

Ver mi código a continuación, por ejemplo:

Estas son las variables del objeto principal:

var tails = [SKEmitterNode]() var tailIndex = 0

En la función de inicio de su cabeza crea una instancia de los objetos de la cola:

for _ in 0...MAX_TAIL_INDEX { if let remnant = SKEmitterNode(fileNamed: "FireTail.sks") { p.tails.append(remnant) } }

Llame al siguiente cuadro por cuadro:

func drawTail() { if tails.count > tailIndex { tails[tailIndex].resetSimulation() tails[tailIndex].particleSpeed = velocity() / 4 tails[tailIndex].emissionAngle = zRotation - CGFloat(M_PI_2) // opposite direction tails[tailIndex].position = position tailIndex = tailIndex < MAX_TAIL_INDEX ? tailIndex + 1 : 0 } }

El efecto resultante es muy suave cuando lo llamas desde la función de actualización de escena ().

Me han pedido que simplifique esta pregunta, así que eso es lo que estoy haciendo.

Estoy luchando en las articulaciones físicas de SpriteKit (y posiblemente en las propiedades físicas del cuerpo). Probé todas las subclases y muchas configuraciones, pero parece que nada funciona o estoy haciendo algo mal.

Estoy desarrollando el juego Snake. El usuario controla la cabeza de la serpiente, que debe moverse a velocidad constante hacia adelante y el usuario puede girarla en sentido horario o antihorario. Todas las piezas restantes de la serpiente deberían seguir la cabeza: deberían viajar exactamente en la misma dirección que la cabeza hace algún tiempo.

Creo que para este juego la unión Pin debería ser la respuesta, cuyo punto de anclaje está exactamente en el centro entre los elementos.

Lamentablemente, el resultado no es perfecto. La estructura debería formar el círculo perfecto, pero no es así. Adjunto el código y el GIF muestra el efecto actual. ¿Alguien tiene experiencia suficiente para darme alguna sugerencia sobre qué propiedades del cuerpo físico o de las articulaciones se deben aplicar aquí para obtener el efecto deseado?

Mi código:

class GameScene: SKScene { private var elements = [SKNode]() override func didMove(to view: SKView) { physicsWorld.gravity = CGVector(dx: 0, dy: 0) let dummyTurnNode = SKNode() dummyTurnNode.position = CGPoint(x: size.width / 2 - 50, y: size.height / 2) let dummyTurnBody = SKPhysicsBody(circleOfRadius: 1) dummyTurnBody.isDynamic = false dummyTurnNode.physicsBody = dummyTurnBody addChild(dummyTurnNode) for index in 0..<5 { let element = SKShapeNode(circleOfRadius: 10) let body = SKPhysicsBody(circleOfRadius: 10) body.linearDamping = 0 // body.mass = 0 element.physicsBody = body element.position = CGPoint(x: size.width / 2, y: size.height / 2 - 30 * CGFloat(index)) elements.append(element) addChild(element) let label = SKLabelNode(text: "A") label.fontSize = 10 label.fontName = "Helvetica-Bold" element.addChild(label) if index == 0 { element.fillColor = UIColor.blue() body.velocity = CGVector(dx: 0, dy: 30) let dummyTurnJoint = SKPhysicsJointPin.joint(withBodyA: dummyTurnBody, bodyB: body, anchor: dummyTurnNode.position) physicsWorld.add(dummyTurnJoint) } else { body.linearDamping = 1 element.fillColor = UIColor.red() let previousElement = elements[index - 1] let connectingJoint = SKPhysicsJointPin.joint(withBodyA: previousElement.physicsBody!, bodyB: body, anchor: CGPoint(x: size.width / 2, y: size.height / 2 - 30 * CGFloat(index) + CGFloat(15))) physicsWorld.add(connectingJoint) } } } override func update(_ currentTime: TimeInterval) { let head = elements.first!.physicsBody! var velocity = head.velocity velocity.normalize() velocity.multiply(30) head.velocity = velocity } } extension CGVector { var rwLength: CGFloat { let xSq = pow(dx, 2) let ySq = pow(dy, 2) return sqrt(xSq + ySq) } mutating func normalize() { dx /= rwLength dy /= rwLength } mutating func multiply(_ factor: CGFloat) { dx *= factor dy *= factor } }