FPS cae y el juego se ralentiza – Sprite-Kit y Swift

Tengo un juego con Sprite-Kit y Swift donde genero círculos aleatorios que caen desde la parte superior de la pantalla hasta la parte inferior de la pantalla.

Al iniciar el juego, funciona perfectamente bien al principio (alnetworkingedor de 60 FPS o less), pero luego el FPS cae gradualmente y el juego se vuelve extremadamente lento … No entiendo por qué el FPS cae con el time (el número de los nodos se mantienen bien en torno a 8-10, por lo que se eliminan cuando salen de la pantalla) – Lo probé tanto en el simulador de iOS como en un dispositivo real, ¿alguna idea?

Lo he comprobado, el problema no viene de una pérdida de memory. Además, estoy usando solo un controller de vista.

La única function que creo que podría causar este problema es esta, pero no sé por qué:

/* Function to generate single random circle */ func generateCircle() -> Void { let circleSize:CGFloat = CGFloat(arc4random_uniform(40) + 3) let xPosition:CGFloat = CGFloat(arc4random_uniform(UInt32(size.width))) var randomCircle = SKShapeNode(circleOfRadius: circleSize) randomCircle.strokeColor = SKColor.networkingColor() randomCircle.fillColor = SKColor.networkingColor() randomCircle.physicsBody = SKPhysicsBody(circleOfRadius: circleSize) randomCircle.physicsBody?.dynamic = false randomCircle.position = CGPoint(x: xPosition, y: size.height + circleSize*2) randomCircle.physicsBody?.dynamic = true randomCircle.physicsBody?.categoryBitMask = randomCirclesGroup addChild(randomCircle) } 

Tal vez hay una pérdida de memory.

  1. Lanza tu juego con Xcode.
  2. Abra el panel Xcode Debug Navigator con CMD + 6 .
  3. Seleccione Memoria y espere a ver si la memory asignada crece.

Si esto sucede, me refiero a si la memory asignada continúa creciendo, incluso cuando usted sabe que no debería hacerlo, entonces está perdiendo memory.

Y la mejor herramienta para encontrar dónde está exactamente el problema en su código es Instruments .

He tenido esto antes, el recuento de nodos hace que parezca que se han ido, pero en realidad no lo son.

Debes eliminar los círculos de la vista para deshacerte de ellos realmente.

Primero definirías un set (dentro de tu class, pero no dentro de ninguna function)

  let circles = Set<SKShapeNode>() 

entonces en la function generateCircle() dirías:

  circles.insert(randomCircle) 

Luego, en la function de update() :

  override func update(currentTime: CFTimeInterval){ for index in circles { if index.position.y <= 0 { index.removeFromParent() circles.remove(index) } } } 

Básicamente lo que hace es, en cada fotogtwig, comprobar si alguno de los círculos está más bajo que la parte inferior de la pantalla, y los borra si lo son.

SKShapeNode tiene peor performance en comparación con SKSpriteNode y uno debería intentar evitar el uso de SKShapeNode si es posible.

De la documentation de Apple :

Los nodos de forma son útiles para el contenido que no se puede descomponer fácilmente en sprites con textura simple. Los nodos Shape también son muy útiles para crear y mostrar información de debugging en la parte superior del contenido del juego. Sin embargo, la class SKSpriteNode ofrece un mayor performance que esta class, por lo que use los nodos de forma moderadamente.

Si realmente quieres usar SKShapeNode (quizás porque es fácil para SKShapeNode prototypes), te aconsejo que hagas lo siguiente:

  • Cree texturas para sus forms una sola vez, quizás cuando la escena se cargue.
  • Caché las texturas renderizadas. En su situación, un dictionary con tamaño y textura parece apropiado, p. Ej. [CGSize: SKTexture] .
  • A partir de ahí, siempre que necesite una forma, recupere la textura del caching y SKSpriteNode usando un SKSpriteNode .

Para representar un SKShapeNode en una textura , puede usar la function textureFromNode de textureFromNode :

Muestra el contenido de un tree de nodos y devuelve la image representada como una textura SpriteKit.