tutorial spritekit game cross ios performance swift sprite-kit frame-rate

ios - game - spritekit tutorial



FPS cae y el juego se ralentiza-Sprite-Kit y Swift (3)

Tal vez hay una pérdida de memoria.

  1. Inicie su juego con Xcode.
  2. Abra el panel Xcode Debug Navigator con CMD + 6 .
  3. Seleccione Memoria y espere para ver si la memoria asignada crece.

Si esto sucede, me refiero a que si la memoria asignada continúa creciendo incluso cuando sabes que no debería, entonces estás perdiendo memoria.

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

Tengo un juego que usa 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 lanzar el juego, funciona perfectamente bien al principio (alrededor de 60 FPS o menos) pero luego el FPS cae gradualmente y el juego se vuelve extremadamente lento ... No entiendo por qué el FPS cae con el tiempo (el número de los nodos se mantienen bien alrededor de 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 proviene de una pérdida de memoria. Además, estoy usando solo un controlador de vista.

La única función 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.redColor() randomCircle.fillColor = SKColor.redColor() 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) }


He tenido esto antes, el número de nodos hace que parezca que se han ido, pero realmente no lo son.

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

Primero definirías un conjunto (dentro de tu clase, pero no dentro de ninguna función)

let circles = Set<SKShapeNode>()

luego en la función generateCircle() dirías:

circles.insert(randomCircle)

Luego, en la función 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 fotograma, comprobar si alguno de los círculos está más abajo que la parte inferior de la pantalla y eliminarlos si lo están.


SKShapeNode tiene un rendimiento peor en comparación con SKSpriteNode y uno debe tratar de evitar el uso de SKShapeNode si es posible.

De la documentación de Apple :

Los nodos de forma son útiles para contenido que no se puede descomponer fácilmente en sprites texturizados simples. Los nodos de forma también son muy útiles para crear y mostrar información de depuración sobre el contenido de tu juego. Sin embargo, la clase SKSpriteNode ofrece un rendimiento superior a esta clase, por lo tanto, use los nodos de forma con moderación.

Si realmente desea utilizar SKShapeNode s (tal vez porque es fácil para la creación de prototipos) , le aconsejaría que haga lo siguiente:

  • Crea texturas para tus formas una sola vez, tal vez cuando la escena se cargue.
  • Guarda en caché las texturas renderizadas. En su situación, un diccionario con tamaño y textura parece apropiado, por ejemplo [CGSize: SKTexture] .
  • A partir de ese momento, cada vez que necesite una forma, recupere la textura de la memoria caché y SKSpriteNode con un SKSpriteNode .

Para convertir un SKShapeNode en una textura , puede usar la función textureFromNode de textureFromNode :

Representa el contenido de un árbol de nodos y devuelve la imagen renderizada como una textura de SpriteKit.