1. Introducci贸n
Actualmente cuando se quiere desarrollar un videojuego lo primero a tener en cuenta es sobre que entorno, librer铆a o ayuda apoyarse para una mayor velocidad y f谩cil desarrollo. Hasta hace poco relativamente iOS solo contaba para el desarrollo de videojuegos con OpenGL y elementos de bajo nivel (supon铆a una dificultad y conocimientos previos enormes) y por otra parte framework o motores de terceros destacando Cocos2D.
Pero desde que Apple introdujo en su SDK el framework SpriteKit todo esto ha cambiado. En este art铆culo aprenderemos los principales conceptos de SpriteKit para posteriormente profundizar con alg煤n ejemplo.
2. SpriteKit
SpriteKit es un framework o librer铆a que proporciona un motor de renderizado y f铆sicas e infraestructura para la creaci贸n de animaciones de im谩genes o sprites. SpriteKit usa un tradicional bucle de renderizado donde los contenidos de cada frame son procesados antes de que el frame sea renderizado. El juego determina el contenido de la escena y como estos contenido cambian en cada frame. SpriteKit hace el trabajo de renderizado de frames eficientemente usando el hardware gr谩fico. Est谩 optimizado para que las posiciones de los sprites puedan ser cambiadas en cada frame de la animaci贸n.
SpriteKit por supuesto tambi茅n incluye otras funcionalidades muy 煤tiles para el desarrollo de juegos. Incluye un soporte para reproducir sonidos y simulaci贸n de f铆sicas. Adem谩s Xcode provee de soporte para SpriteKit proporcionando entorno para crear efectos y atlas de texturas en Xcode. Esta combinaci贸n de librer铆a y herramientas hacen de SpriteKit una buena elecci贸n para juegos y otras app que este tipo de animaciones. (En caso de necesitar otro tipo de animaciones de la interfaz de usuario usar CoreAnimation).
2.1 Principales Clases
Principalmente existen las siguientes clases:
- SKView: es el canvas , lienzo o vista sobre el que ese trabaja con las clases de SpriteKit.
- SKScene: representa cada pantalla de nuestro juego, por ejemplo el men煤, opciones, escena de juego, de compras, etc.
- SKNode: es la clase m谩s importante y representa cada elemento de nuestro videojuego como el personaje, l铆mites, disparos, etc. M谩s adelante veremos las diferentes subclases en las que se divide explicando para que es el uso de cada una, as铆 como algunos propiedades y m茅todos interesantes que ofrezcan.
- SKAction: permite crear acciones que posteriormente se pueden aplicar a un SKNode (escalado, traslaciones, ...)
- SKPhysics: clase encargada de agregar la f铆sica a un SKNode para que se vea afectado por la gravedad, choques, fuerzas, etc.
A continuaci贸n vamos a ir viendo con m谩s detalle cada clase.
2.1.1 SKView
Lo mismo que cuando se quiere trabajar con mapas es necesario hacer uso de MKMapView o en caso de contenido web con UIWebView si queremos mostrar contenido de SpriteKit debemos usar SKView.
Hay varios par谩metros destacables que se pueden configurar de una SKView:
- showsDrawCount: n煤mero de operaciones de pintado que requiere la escena.
- showsNodeCount: n煤mero de SKNode en pantalla.
- showsFPS : n煤mero de fotogramas por segundo que est谩 ofreciendo la app.
- showsPhysics: para mostrar las f铆sicas, es decir realmente que colisiona.
Normalmente hay que inicializar la vista del controlador como SKView en el m茅todo viewDidLoad o por comodidad mediante el interfaz gr谩fico indicar que sea de tipo SKView.
2.1.2 SKScene
Las subclases de SKScene que se van creando a lo largo del desarrollo del videojuego representan las diferentes pantallas del mismo. Se trata de una subclase de SpriteKit. Siempre que se quiera mostrar elementos en pantalla ser谩 a trav茅s de una SKScene. A su vez para mostrar la SKScene hay usar la SKView que sirve de contenedor para todo lo que queramos utilizar de SpriteKit. De hecho es posible gracias a SKView mezclar contenido de UIKit y SpriteKit (algo a m铆 intento un poco lioso y pesado, aunque viable).
SKScene sigue un bucle de ejecuci贸n con los siguientes pasos:
- M茅todo update
- Se ejecutan las acciones
- M茅todo didEvaluateActions
- Se ejecutan las simulaciones f铆sicas
- M茅todo didSimulatePhysics
En la imagen inferior vemos gr谩ficamente el bucle.
![]() |
| Fig. 2. Bucle en SKScene (y en SKView) |
Adem谩s de estos m茅todo otros a tener en cuenta ser铆an:
- didMoveToView: se ejecuta una vez la vista es presentada en pantalla. En este m茅todo se incluyen en la escena todos los elementos que formar谩n parte de ella.
- touchesBegan/Moved/Ended/Cancelled: m茅todos disponibles en los SKNode para detectar toques sobre ellos.
En la imagen inferior a帽adimos el c贸digo para crear y presentar una escena a la SKView del controlador.
![]() |
| Fig. 3. A帽adir una escena a una SKView y presentarla |
2.1.3 SKNode
Representa de forma abstracta pr谩cticamente la totalidad de los elementos que conforma el videojuego. A continuaci贸n mencionaremos cada uno de ellos as铆 como su funci贸n.
- SKSpriteNode: se utiliza para mostrar un sprite. No solo una imagen, sino colores o combinaci贸n de estos pudiendo modificar el alpha, la escala, rotaci贸n o color.
- SKTexture: permite mostrar una informaci贸n gr谩fica en pantalla. Principalmente se usa su inicializador el cual acepta un UIImage, aunque hay otro como con CGImage o NSData. Para poder mostrar el SKTexture en pantalla es necesario un SKSpriteNode que lo contenga.
- SKEmitterNode: nos permite incluir en la escena sistemas de part铆culas en 2D, fijas o animadas. Se pueden definir texturas, escala, rotaci贸n, 谩ngulo de emisi贸n, velocidad de emisi贸n y otros. Para todo esto se puede usar el editor de part铆culas que trae Xcode.
- SKVideoNode: permite incluir un video. Se puede hacer uso de AVPlayer para poder controlar la reproducci贸n, pausar, etc.
- SKShapeNode: permite mostrar formas geom茅tricas, cualquier CGPath. Para dichas formas permite definir el color de borde y color de relleno, o hacer efectos.
- SKLabelNode: lo mismo que usar el de UIKit pero permite acciones y efectos sobre el texto y soporta todas las fuentes disponibles en el sistema.
- SKEffectNode: nos permite aplicar efectos de CoreImage a la estructura de nodos que dependen de este SKEffectNode.
- SKCropNode: ofrece la posibilidad de recortar contenido de un nodo en base a una m谩scara, es decir transparentar una capa inferior a trav茅s de una capa superior.
Con todas estas clases se pueden crear estructuras jer谩rquicas m谩s complejas.
2.1.4 SKAction
Es la clase que nos permite multitud de posibilidad a la hora de animar un SKNode.
- Cambiar su posici贸n (traslaci贸n)
- Cambiar su tama帽o (escalado)
- Cambiar su visibilidad
- Cambiar sus texturas para aplicar animaciones fotograma a fotograma
- Colorear el sprite
- Reproducir sonidos
- Eliminar el nodo de la jerarquia
- Acciones personalizadas que podemos definir en un bloque(block) o secuencia (sequence).
- Definir acciones infinitas o que se repiten un determinado n煤mero de veces
2.1.5 SKPhysics
La simulaci贸n de f铆sicas permite aplicar a los objetos irreales propiedades y comportamiento del mundo real, como la gravedad, masa, elasticidad, rozamientos, etc.
En SpriteKit esto se traduce en la clase SKPhysicsBody, que a la vez esta siempre conectada a un SKNode. Para configurar las propiedades del mundo virtual se cuenta con la clase SKPhysicsWorld, muy t铆picamente la gravedad por medio de gravity.
Hay que definir entre dos tipos de cuerpos f铆sicos:
- Basados en volumen:permiten simular cuerpos que tiene un volumen y masa terminada. A su vez pueden ser din谩micos o est谩ticos.
- Basados en bordes: no tienen ni volumen ni masa y normalmente se usan para definir los bordes de la pantalla.
Para crear cuerpos basados en volumen tenemos tres inicializadores (y alguno m谩s):
- bodyWithCircleOfRadius: para c铆rculos
- bodyWithRectangleOfSize: para rect谩ngulos
- bodyWithPolygonFromPath: para pol铆gonos
Y para cuerpos basados en bordes:
- bodyWithEdgeLoopFromRect: crea los bordes definidos por un CGRect
- bodyWithEdgeFromPoint:toPoint: crea el borde de un punto a otro
- bodyWithEdgeLoopFromPath: crea el borde definido por un CGPath
- bodyWithEdgeChainFromPath: crea un borde definido por un CGPath
Por 煤ltimo mencionar las propiedades m谩s importantes de los cuerpos f铆sicos:
- mass: masa del objeto, la cual afecta directamente a las fuerzas as铆 como a la inercia.
- friction: fricci贸n ofrecida por el objeto. Por defecto tiene un valor de 0.2
- linearDumping y angularDumping: amortiguaci贸n linear y angular del objeto, y sirve para simular fricci贸n con el aire o agua.
- restitution: cantidad de energ铆a que se pierde en una colisi贸n, es decir capacidad de rebote. Por defecto 0.2.
- dynamic: define si el cuerpo se ve afectado o no por las fuerzas aplicadas sobre 茅l. En caso de que no sea din谩mico es est谩tico.
- affectedByGravity: determina si la gravedad le afecta
- allowsRotation: si el objeto puede rotar o no.
Decir que se pueden aplicar fuerzas y velocidades a los cuerpos mediante m煤ltiples m茅todos, aunque no los comentar茅 debido a que se alarga mucho el tutorial.
Por 煤ltimo respecto a f铆sicas comentar que como determinar la interacci贸n entre dos o m谩s cuerpos. Existen dos conceptos para esto:
- Contacto o contact:nos sirve para conocer cuando dos objetos est谩n en contacto.
- Colisi贸n o collision: mecanismo que evita que dos cuerpos compartan el mismo espacio f铆sico. El propio SpriteKit calcula el impulso resultante y se aplica.
A parte ya que puede que queramos que no todos interacciones con todos sino por grupos se definen:
- categoryBitMask:define la categor铆a
- collisionBitMask: define con qu茅 categor铆as de objetos puede colisionar
- contactTestBitMask: define con qu茅 categor铆as de cuerpos puede entrar en contacto
Una vez definidos las m谩scaras sencillamente declaramos la escena como delegada del tipo SKPhysicsContactDelegate mediante la propiedad contactDelegate del SKPhysicsWorld e implementamos el m茅todo didBeginContact.
Por 煤ltimo mencionar que permite la creaci贸n de diferentes tipos de uniones. Las uniones son sencillamente conexiones entre objetos y su ventaja es que son tenidas en cuenta por las fuerzas que se aplican en los cuerpos. Por mencionarlas tenemos: SKPhysicsJointFixed, SKPhysicsJointSliding, SKPhysicsJointSpring, SKPhysicsJointLimit y SKPhysicsJointPin. Cada una tiene un objetivo y ofrece distintas posibilidades.
3. Mini Proyecto
En esta secci贸n se desarrollar谩 un peque帽o juego cuya principal funci贸n es poner en pr谩ctica los principales conceptos visto en la secci贸n anterior. Para ello se buscara lo siguiente a lo largo de la secci贸n:
- Transiciones entre escenas para implementar lo que ser铆a un men煤 y una escena de juego.
- Trabajar con SKNode: crear, a帽adirlo y animarlos.
- A帽adir f铆sicas a los nodos.
3.1 Creaci贸n del Proyecto y su puesta a punto
Para crear el proyecto nos situamos en la ventana de inicio de Xcode (si no se abre Window->Welcome To Xcode) y seleccionamos la plantilla Game perteneciente a iOS. A continuaci贸n introducimos el nombre, en mi caso Test, y el resto de elementos como se muestra en la Fig. 3.
![]() |
| Fig. 3. Nuevo Proyecto |
Una vez se ha creado el proyecto hay que eliminar todo lo se crea por defecto y no har谩 falta. Estas son las cosas a modificar:
- Quitar del m茅todo viewDidLoad de la clase GameViewController todo lo que va despu茅s de la l铆nea:
skView.ignoresSiblingOrder = true
- Eliminar lo que contiene el m茅todo touchesBegan en la clase GameScene
- Por 煤ltimo por una parte borrar el archivo GameScene.sks ya que sirve para crear una escena gr谩ficamente y no lo usaremos. Y por otra si se quiere la imagen Spaceship que no la usaremos.
Una vez hecho esto tenemos nuestra plantilla lista para comenzar.
3.2 Transiciones entre escenas.
En esta parte vamos a crear una escena para el men煤 y a帽adiremos un bot贸n para pasar a la escena de juego.
Para empezar creamos una nueva subclase de SKScene a la que llamaremos MenuScene.
Una vez creada vamos a ir a la clase GameViewController y vamos hacer que esta presente la escena del men煤. Para ello en el m茅todo viewDidLoad a帽adimos al final el siguiente c贸digo:
Con estos simples pasos hemos creado una escena y hemos hecho que el controlador la presente inicialmente. Hasta ahora si ejecutamos no mostrar谩 nada ya que la escena del men煤 esta vac铆a por ahora.
Vamos a empezar a crear nuestro sencillo men煤. El men煤 contar谩 con un t铆tulo y un bot贸n centrar para iniciar el juego, de play.
La creaci贸n de todos los elementos iniciales se hace en el m茅todo didMoveToView el cual se ejecuta una vez la escena es presentada. Lo primero ser谩 cambiar el color de fondo de la escena por ejemplo a un naranja. Para ello a帽adimos:
Ahora s铆 vamos a empezar creando el t铆tulo. Para la creaci贸n se objetos en pantalla mi recomendaci贸n es hacerlo todo proporcional al tama帽o de la vista que se tiene, ahora lo ir茅is entendiendo. Para ello declaramos las siguientes variables que se corresponde al ancho, alto de la pantalla y sus mitades.
Haciendo uso de estas variables creamos y situamos el t铆tulo:
Ahora para el bot贸n podr铆amos usar otro SKLabelNode pero vamos a crear un SKSpriteNode con una imagen en este caso para que quede mucho mejor.
En este caso no voy a entrar en tema de tama帽os y con ello resoluci贸n y escala seg煤n el dispositivo pero hay que tenerlo en cuenta. Una vez aclarado esto a帽adimos la imagen a Images.xcassets y a帽adimos lo siguiente para crear nuestro bot贸n:
Si ejecutamos ahora mismo obtendremos algo similar a la Fig. 6, pero hasta ahora si pulsamos sobre el bot贸n no tenemos ning煤n acci贸n.
Para empezar creamos una nueva subclase de SKScene a la que llamaremos MenuScene.
![]() |
| Fig. 4. Creamos la clase MenuScene |
let scene = MenuScene(size: skView.bounds.size)
/* Set the scale mode to scale to fit the window */
scene.scaleMode = .AspectFill
skView.presentScene(scene)
Con esto el m茅todo quedar铆a como en la Fig. 5:
![]() |
| Fig. 5. M茅todo ViewDidLoad |
Vamos a empezar a crear nuestro sencillo men煤. El men煤 contar谩 con un t铆tulo y un bot贸n centrar para iniciar el juego, de play.
- Para el t铆tulo usaremos un SKLabelNode
- Para el bot贸n usaremos un SKSpriteNode. Pensareis que podr铆amos usar un UIButton y llev谩is raz贸n pero incluirlos aumenta la complejidad. ¡Os animo a probar con ellos!
self.backgroundColor = UIColor.orangeColor()
var frame = self.frame;
var _W:CGFloat = frame.size.width;
var _H:CGFloat = frame.size.height;
var _w:CGFloat = frame.size.width * 0.5;
var _h:CGFloat = frame.size.height * 0.5;
let titleLabel = SKLabelNode(fontNamed: "Chalkduster")
titleLabel.text = "Test";
titleLabel.fontColor = UIColor.whiteColor()
titleLabel.fontSize = 60.0
titleLabel.position = CGPointMake(_w, _H * 0.9 - titleLabel.frame.size.height * 0.5);
self.addChild(titleLabel);
let playButton = SKSpriteNode(imageNamed: "play");
playButton.position = CGPointMake(_w, _h);
playButton.name = "PlayButton"
self.addChild(playButton)
![]() |
| Fig. 6. Muestra del Men煤 |
Para detectar los toques sobre la pantalla sobreescribiremos el m茅todo touchesBegan sencillamente ya que solo queremos detectar un simple toque. En este haciendo uso del nombre que le hemos asignado al bot贸n podremos detectar los toques sobre 茅l. En la Fig. 7 se ve como quedar铆a el m茅todo.
![]() |
| Fig. 7. M茅todo TouchesBegan en escena Men煤 |
En este m茅todo sencillamente se obtienen el nodo sobre el que se pulsa y se comprueba si es el bot贸n. En caso de que s铆 se crea una transici贸n y la nueva escena y se le dice a la visa que lleve a cabo su presentaci贸n.
Si ejecutamos el proyecto veremos como se puede pasar a la escena de juego donde aparecer谩 el texto Hello World sino lo hemos borrado antes.
3.2 Trabajar con SKNode: Crear y A帽adir a la Escena
En el apartado anterior ya hemos visto como usar dos de los SKNode, el primero de ellos un SKLabelNode y para el bot贸n un SKSpriteNode al que le hemos puesto una foto. En este apartado vamos a trabajar un poco m谩s subclases de SKNode. Debido a que no resulta un poco pesado buscar im谩genes en vez de usar SKSpriteNode vamos a usar SKShapeNode para crear figuras en especial c铆rculos de colores. A estas figuras le a帽adiremos algunas animaciones y en el siguiente apartado le a帽adiremos f铆sicas.
Vamos a crear dos bolas, una de color azul y otra de color rojo, y las pondremos centradas en la pantalla. Y le a帽adiremos una animaci贸n diferente a cada una cuando pulsemos sobre ellas. Para ello, se a帽ade el c贸digo de la Fig. 8 en el m茅todo didMoveToView de la escena juego.
![]() |
| Fig. 8. A帽adimos 2 bolas a la escena |
Atenci贸n al nombre que le hemos puesto a cada bola ya que lo usaremos para aplicar una animaci贸n a cada una de ellas. Por ejemplo a la azul vamos a hacer que aumente su tama帽o al doble y vuelva a su estado normal. Y para la roja haremos que desaparezca y vuelva a aparecer. Para ello usaremos la clase SKAction la cual nos permite mediante el m茅todo Sequence a帽adir varias SKAction secuencialmente. En la Fig. 9. vemos como se ha hecho en unas pocas l铆neas.
![]() |
| Fig. 9. A帽adir animaciones a las bolas cuando pulsamos sobre ellas |
Hasta ahora deber铆amos tener algo similar a la Fig. 10, en la cual tenemos dos bolas y si pulsamos sobre alguna de ellas se ejecuta la animaci贸n correspondiente.
![]() |
| Fig. 10 Escena Juego con las bolas y las animaciones |
Con esto damos por terminada esta secci贸n, vamos a la siguiente que es la m谩s divertida, !jugar con las f铆sicas!
3.3 Jugar con las F铆sicas
En esta 煤ltima secci贸n queremos a帽adir f铆sicas a las bolas para que se muevan por la pantalla. Antes de ellos vamos a crear los l铆mites de la pantalla para que no se escapen. Para los bordes vamos a crear un SKSpriteNode denominado Playground al cu谩l le vamos a a帽adir f铆sicas de tipo borde. Lo m谩s complicado de entender son las m谩scaras pero si prestamos atenci贸n le asignamos como categor铆a la 1, y como m谩scara de colisi贸n tiene el m谩ximo es decir todo chocar谩 con 茅l. En cuanto a la m谩scara de contacto es 0 por lo que no habr谩. Lo mejor para comprender es toquetear y ver el comportamiento.
![]() |
| Fig. 11. Creamos el Playground |
Una vez creados los bordes o l铆mites a帽adimos el c贸digo de la Fig. 12 cada parte a su correspondiente bola. Si lo analizamos estamos haciendo que las bolas choquen con los bordes pero no entre s铆.
![]() |
| Fig. 12. A帽adir f铆sicas a las bolas |
La bola azul tiene la categor铆a 2 y la roja la 4 (tienen que ser potencias de dos), y como colisi贸n solo tiene la categor铆a de los bordes que es 1. De este modo se tiene el comportamiento que quer铆amos. Para apreciar que esta todo correcto a帽adir esta l铆nea cuando hacemos las animaciones para que las bolas reciban una fuerza y cambien su trayectoria y se crucen:
node.physicsBody?.applyForce(CGVectorMake(500,500))
Tambi茅n podeis a帽adir esta l铆nea en el controlador para que se muestren las f铆sicas lo que es muy c贸modo mientras se desarrolla un juego.
skView.showsPhysics = true
FIN
Espero que os haya gustado el tutorial. Me hubiera gustado explicar tantas cosas pero son demasiadas para abarcarlas todas. Yo creo que con esta breve introducci贸n y ejemplos es suficiente para iniciarse y que la curiosidad haga el resto.
Para cualquier duda o sugerencia que quer谩is preguntar ponerlo en los comentarios.
Enlace directo del proyecto completo SpriteKitTest
Enlace del proyecto en GitHub: SpriteKitTest



































