Advertisement
  1. Code
  2. SpriteKit

Crea invasores del espacio con Swift y Sprite Kit: introduciendo Sprite Kit

Scroll to top
Read Time: 9 min
This post is part of a series called Create Space Invaders with Swift and Sprite Kit.
Create Space Invaders With Swift and SpriteKit: Implementing Classes

() translation by (you can also view the original English article)

Final product imageFinal product imageFinal product image
What You'll Be Creating
Final product imageFinal product imageFinal product image
Lo que vas a crear

En ésta serie, te enseñaré como crear unos Invasores del Espacio inspirados en el juego usando Sprite Kit y el lenguaje de programación Swift. A lo largo del camino, aprenderás sobre el motor de física integrado de Sprite Kit, generar partículas usando el editor de partículas integrado de Sprite Kit, usar el acelerómetro para mover el jugador y mucho más. Comencemos.

Introduciendo Sprite Kit

Sprite Kit es el motor de juegos 2D de Apple que fue introducido con iOS 7. Con la introducción del lenguaje de programación Swift en el 2014, nunca hubo un mejor tiempo para ser un desarrollador de juegos para iOS.

Sprite Kit proporciona un motor de renderizado construido sobre el estándar gráfico OpenGL. Con el uso de sprites con texturas, un motor de física integrado, y la muy poderosa clase SKAction, puedes crear muy rápidamente juegos 2D funcionales.

Bucle de Renderizado

Sprite Kit, como la mayoría de los motores de juego, utiliza un bucle para renderizar y actualizar la pantalla. El bucle de renderizado tiene varios pasos que cubre antes de renderizar la escena actual. Son los siguientes:

  1. Actualizar
  2. Evaluar acciones
  3. Simular física
  4. Aplicar restricciones
  5. Renderizar la escena

Cada uno de éstos tiene un método correspondiente que puedes usar para aplicar cualquier lógica adicional que necesita realizarse en ese tiempo dentro del marco. Específicamente, usarías los siguientes métodos dentro de la escena.

  1. update
  2. didEvaluateActions
  3. didSimulatePhysics
  4. didApplyConstraints
  5. didFinishUpdate

Estamos interesados en dos de éstos métodos para éste tutorial, update y didSimulatePhysics. Usaremos el método update para mover a los invasores manualmente y el método didSimulatePhysics para actualizar al jugador, que será controlado usando el acelerómetro y el motor de física.

SKNode

Uno de los bloques que conforman el framework Sprite Kit es la clase SKNode. La clase SKNode no genera ningún recurso visual. Su papel principal es proporcionar un comportamiento base que implementan otras clases. La clase SKScene es el nodo raíz en un árbol de instancias SKNode y es usada para albergar sprites y otro contenido que necesita ser renderizado.

El renderizado y la animación se hacen por una instancia SKScene que se coloca dentro de una ventana y otras vistas son añadidas a élla después. La instancia SKScene se añade a la instancia SKView. Puedes usar una sola instancia SKView en tu ventana y cambiar entre diferentes escenas en cualquier momento.

El framework define un número de subclases de SKNode. La más común para crear una escena es la clase SKSpriteNode. La clase SKSpriteNode puede ser dibujada como un rectángulo con  SKTexture contenido en ella, o como un rectángulo con textura y color. Con frecuencia usarás sprites con textura, porque es así como tu trabajo cobra vida en tu juego. Checa el árbol de herencia de la clase SKNode para ver que otros tipos de nodos están disponibles.

SKAction

La clase SKAction es lo que dan vida a tus clases SKNode. Al usar la clase SKAction puedes mover, rotar, escalar y desvanecer los nodos.  También puedes usar SKAction para reproducir un sonido y ejecutar código. La clase SKAction es muy poderosa, y junto con la clase SKNode, es uno de los bloques que conforman un juego de Sprite Kit.

Motor de Fisica

Sprite Kit tiene un motor de física integrado que hace muy fácil el manejo de situaciones físicas complejas. Si alguna vez has tratado de implementar un motor de física por tí mismo, apreciarás ésta característica.

En Sprite Kit, la coordenada (0,0) se localiza en la parte inferior izquierda de la pantalla en lugar de la parte superior izquierda, como podrías estar acostumbrado si has trabajado con Flash, Corona, HTML5 Canvas, y muchos otros frameworks para juegos. Ésto es porque Sprite Kit utiliza OpenGL bajo la máscara.

Te sugiero ampliamente leer la Guía de Programación para Sprite Kit de Apple para familiarizarte más con los conceptos mencionados anteriormente. Dejando atrás  ésta breve introducción, comencemos a construir un juego con Sprite Kit.

1. Establecer el Proyecto

Abre Xcode y elige Create a new Xcode project ó elige New>Project.. del menu File.

Create New ProjectCreate New ProjectCreate New Project

Asegúrate de que tu target sea iOS, que el tipo sea Application, y que hayas elegido Game como tu tipo de plantilla. Haz click en Next para continuar.

Choose Project TemplateChoose Project TemplateChoose Project Template

Posteriormente elige cualquier cosa que quieras para Product Name (Nombre del Producto),Organization Name (Nombre de la organización), y Identifier Organization (Identificador de la Organización). No olvides establecer Language a Swift, Game Technology a Sprite Kit, y Devices a iPad. Especifica una ubicación para guardar los archivos del proyecto y da click en Create.

Choose Project OptionsChoose Project OptionsChoose Project Options

Si das click para ejecutar el botón en la parte superior izquierda (o presionas Command-R), Xcode compilará y ejecutará tu aplicación, mostrando el texto "Hello, World). Cuando pulses la pantalla, se agregará una imagen de una nave espacial y comenzará a rotar.

Default Game Screen ShotDefault Game Screen ShotDefault Game Screen Shot

2. Configuración del Proyecto

Selecciona el Proyecto en el Project Navigator y abre la pestaña General en la parte superior. En Deployment Info, desmarca todas las casillas de verificación menos Portrait en Device Orientation.

Después, selecciona y borra GameScene.sks. El archivo .sks te permite conformar la escena visualmente. Para éste proyecto, estaremos añadiendo cada nodo programáticamente. Abre GameViewController.swift, borra su contenido, y remplázalo con lo siguiente.

1
import UIKit
2
import SpriteKit
3
4
class GameViewController: UIViewController {
5
    
6
    override func viewDidLoad() {
7
        super.viewDidLoad()
8
        let scene = StartGameScene(size: view.bounds.size)
9
        let skView = view as SKView
10
        skView.showsFPS = true
11
        skView.showsNodeCount = true
12
        skView.ignoresSiblingOrder = true
13
        scene.scaleMode = .ResizeFill
14
        skView.presentScene(scene)
15
    }
16
    
17
    override func prefersStatusBarHidden() -> Bool {
18
        return true
19
    }
20
}

La clase GameViewController hereda de UIViewController y tendrá un SKView como su vista. Dentro el método viewDidLoad, transformamos su propiedad view a una instancia SKView y la configuramos.

Puedes haber notado el texto en la esquina inferior derecha de la pantalla cuando ejecutaste la aplicación por primera vez. Para eso son las propiedades showsFPS y showsNodeCount, mostrando el número de cuadros por segundo a los que el juego se ejecuta y el número de SKNodes visibles en la escena.

Si alguno de los nodos se moviera fuera de la pantalla, la cuenta del nodo bajaría, pero continuarían en la memoria. Ésto es importante para recordar y no permitas que la cuenta del nodo te engañe. Si sumas 100 nodos a una escena y 90 de ellos están fuera de la pantalla, aún tienes 100 nodos ocupando la memoria.

Para propósitos de optimización, el ignoresSiblingerOrder se establece a true.  Puedes leer más sobre ésto en la Guía de Programación para Sprite Kit. Lo último que hacemos es invocar al método presentScene de SKView y pasarlo en en StartGameScene, que creará el próximo paso.

Finalmente, no queremos que se muestre la barra de estado así que regresamos true del método preferStatusBarHidden. 

3. Creando StartGameScene

Paso 1:Añadiendo la clase StartGameScene

Elige New>File... del menú File y elige Cocoa Touch Class de la sección iOS>Soure. Da click en Next para continuar.

Create new ClassCreate new ClassCreate new Class

Posteriormente, nombra la clase StartGameScene y asegúrate de que hereda de SKScene. Language debería establecerse a Swift. Da click en Next para continuar.

Especifica a Xcode donde te gustaría guardar el archivo para la nueva clase y da click en Create. Agrega el siguiente código a StartGameScene.swift.

1
import UIKit
2
import SpriteKit
3
class StartGameScene: SKScene {
4
   
5
    override func didMoveToView(view: SKView) {
6
        backgroundColor = SKColor.blackColor()
7
        NSLog("We have loaded the start screen")
8
    }
9
}

El método didMoveToView(_:) es llamado inmediatamente despues de que la escena es presentada por la vista. Generalmente, aquí es donde harás la configuración para tu escena y crearás tus recursos.

i pruebas el juego ahora deberías observar una pantalla negra que muestra el número de cuadros por segundo que está reproduciendo el juego y la cuenta de nodo en la esquina inferior derecha de la pantalla.

Paso 2: Añadiendo startGameButton

No es divertido mirar una pantalla negra así que vamos a crear nuestra primera instancia SKSpriteNode Actualiza el método didMoveToView(_:) como se muestra abajo.

1
override func didMoveToView(view: SKView) {
2
    let startGameButton = SKSpriteNode(imageNamed: "newgamebtn")
3
    startGameButton.position = CGPointMake(size.width/2,size.height/2 - 100)
4
    startGameButton.name = "startgame"
5
    addChild(startGameButton)
6
}

Declaramos una constante startGameButton usando el conveniente inicializador init(imageNamed:), que tomar como argumento el nombre de la imagen. La centramos en la pantalla tanto horizontal como verticalmente, excepto que restamos 100 puntos para colocarla un poco fuera del centro del eje vertical. Establecemos su propiedad name a startgame así podemos ubicarla después. Finalmente, la añadimos a la escena al invocar addChild(_:), que toma como argumento el nodo para añadir a la escena. Puedes aprender más sobre la clase SKSpriteNode en la Guía deReferencia del Framework Spritekit.

Ahora sería un buen momento para agregar las imágenes al proyecto. Descarga los archivos fuente de éste tutorial y busca el directorio llamado images. Arrástralo al directorio que tiene el nombre de tu proyecto, por ejemplo, Mobile TutsInvaderz. Asegúrate de que esté marcado Copy items if needed así como el target principal en la lista de targets.

Adding Images FolderAdding Images FolderAdding Images Folder

Si pruebas tu aplicación, deberás ver un boton con la etiqueta "New Game".

New Game ButtonNew Game ButtonNew Game Button

Paso 3: Implementando touchesBegan

Luego, necesitamos implementar el método touchesBegan(_:withEvent:).  Su implementación se muestra abajo.  El método touchesBegan es invocado cuando uno o más dedos tocan la pantalla.

1
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
2
    for touch: AnyObject in touches {
3
        let touchLocation = touch.locationInNode(self)
4
        let touchedNode = self.nodeAtPoint(touchLocation)
5
        if(touchedNode.name == "startgame"){
6
            let gameOverScene = GameScene(size: size)
7
            gameOverScene.scaleMode = scaleMode
8
            let transitionType = SKTransition.flipHorizontalWithDuration(1.0)
9
            view?.presentScene(gameOverScene,transition: transitionType)
10
            }
11
        }
12
}

La propiedad multiTouchEnabled de la vista de la escena es establecida a false por defecto, lo que significa que la vista sólo recibe el primer toque de una sequencia multitouch (toques múltiples). Con esta propiedad deshabilitada, puedes recuperar el toque al llamar a AnyObject en la serie touches pues sólo hay un objeto en la serie.

Guardamos la ubicación del toque en la escena en una constante llamada touchLocation. Hacemos ésto al invocar locationInNode(_:) en el objeto touch, pasando la escena. Podemos entonces determinar que nodo fue tocado al invocar nodeAtPoint, pasando  la ubicación del toque. Con éste nodo toucheNode encontrado, podemos revisar la propiedad name y, si es igual a startgame, sabemos que ellos pulsaron el botón.

Si el usuario pulsó el botón, hacemos una instancia de la clase GameScene y establecemos su scaleMode similar al modo de escala de la escena actual. Entocnes creamos un SKTransition llamado transitionType y mostramos la escena al invocar presentScene(:_transition) pasando el gameOverScene y el transitionType.

Hay pocos tipos SKTransition para escoger. Puedes leer más sobre ellos en la Guía de Referencia del Framework SpriteKit. Te sugiero que pruebes algunos y veas cuáles te gustan más.

i pruebas tu aplicación, puedes pulsar el botón, que te lleva a GameScene. Ésta es la misma escena con la que inició el proyecto.

Conclusión

Esto concluye la primera parte de ésta serie. Te has iniciado en Sprite Kit y has aprendido como crear escenas, utilizar la clase SKSpriteNode, y detectar toques.  Ésto es sólo el principio, todavía tenemos mucho que aprender. Gracias por leer y nos vemos en la próxima parte de ésta serie.

¡Sé el primero en conocer las nuevas traducciones–sigue @tutsplus_es en Twitter!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.