Bienvenidos

¡Espero que el contentido sea de tu agrado!

Tutorial Corona SDK

Iniciate en Corona SDK para crear aplicaciones y juegos impresionantes en multiples plataformas con rápidez tanto en el aprendizaje como el desarrollo.

CoreData: Compartir Modelo con el Watch Apple

En este tutorial se ve una introducción a CoreData y posteriormente como se puede crear el modelo para que este compartirdo por diferentes entornos, por ejemplo para la extensión para el Watch Apple.

Lector de Códigos de Barras y QR

El objetivo de este tutorial será ver como se implementa un lector de códigos haciendo uso de AVFoundation en Swift.

SpriteKit con Swift

Adentrate en el mundo del desarrollo de videojuegos con SpriteKit

lunes, 25 de mayo de 2015

SpriteKit con Swift


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. 

Fig. 1 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.

Fig. 4. Creamos la clase 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:

         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
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.


  • 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!


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:

        self.backgroundColor = UIColor.orangeColor()        


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.


        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;




Haciendo uso de estas variables creamos y situamos el título:

        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);


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:

        let playButton = SKSpriteNode(imageNamed: "play");
        playButton.position = CGPointMake(_w, _h);

        playButton.name = "PlayButton"
        self.addChild(playButton)


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.

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 








martes, 12 de mayo de 2015

Android 5.0 Lollipop Novedades

Ya ha llegado la nueva versión de Android denominada Lollipop 5.0. En esta entrada vamos a resumir las principales novedades que Android Lollipop introduce sin detallar las increíbles nuevas API que se han añadido disponibles para los desarrolladores.

MATERIAL DESIGN 

Se trata de una nueva filosofía de diseño para la visualización, renderizado e interactividad para todas las plataformas.  Persigue el diseño basado en materiales, buscando los más naturales. Además para mejorar la interactividad llamado la atención del usuario juega con los contrastes tanto en colores como contornos. 

Google ha puesto a la disposición de los diseñadores una gran cantidad de información y toda la documentación para  crear aplicaciones muy atractivas a la vez que se aumenta el rendimiento y fluidez. 


Si tenéis curiosidad, quereis iniciaros o simplemente mejorar vuestras aplicaciones entra aquí


Multimedia y Sonido

Esta parte en mi opinión es más llamativa a nivel de usuario ya que casi todos los usuarios hacen un mayor uso del dispositivo para la reproducción de video o audio así como la cámara. Las principales novedades son:

  • Menor latencia de audio de entrada para una experiencia en tiempo real mejor
  • Audio multicanal hasta 7.1
  • Soporte para audio USB
  • OpenGL ES 3.1
  • Fotografía: máxima resolución con 30fps, soporte para formato RAW, y diferentes ajustes.
  • Tecnología de video art, con soporte para perfil HEVC que permite hasta UHD 4K


Android TV 


Android se presenta como el primero que intenta hacer una único del gran ecosistema. Ya que no solo permitiría la conexión con Android Wear sino que también es la base de Android TV.  Por ejemplo podremos:
  • Tener una interfaz adaptada para la gran pantalla
  • Pensado para una mayor visualización con menor navegación
  • Búsqueda por voz
  • Posiblidad de hacer uso de gamepads
  • Posiblidad de hacer cast con las aplicaciones de entretenimiento

Notificaciones inteligentes

La idea principal es sencillamente que solo se nos debe interrumpir cuando realmente sea necesario.  Para ello se han añadido:
  • Poder responder y ver mensajes directamente desde la pantalla de bloqueo
  • Un sistema de prioridades de notificaciones
  • Una mejor gestión de las notificaciones. 

En mi opinión lo mejor es que las llamadas entrantes no interrumpirán lo que estemos haciendo en un momento dado. En la imagen superior se ve lo que quiero decir. 

Más autonomía


Android Lollipop ha optimizado el uso de la batería haciendo su vida un poquito más larga. Para hacernos una idea se amplia hasta 90 minutos la duración de una misma batería. 

Además ahora ofrece una visualización de la estimación de los tiempo de batería es decir cuanto queda para que se acabe o se cargue. 




Seguridad: Factory reset en caso de robo


Android Lollipop incluye la encriptación automática activada para proteger los datos en caso de pérdida o robo. Pero no todo queda aquí ya que además incluye las siguientes características:

  • SELinux: protección contra malware y vulnerabilidades.
  • Android Smart Lock: protección gracias al emparejamiento con otro dispositivo como el coche o wearable.
  • Google Protección Factor Reset: respetar de fábrica el dispositivo en caso de pérdida o robo. 

Modo multiusuario

Permite la gestión de múltiples usuarios en los teléfonos. Se dispondrá de un usuario invitado el cual tiene acceso pero no al contenido del resto de usuarios. Es parecido a como esta implementado en sistemas operativos de escritorio. Además se puede bloquear un contenido mediante un clave. 


Compatibilidad con accesorios BLE


Se ha intentado mejorar la conectividad con los múltiples dispositivos, sobre todo para evitar interrupciones en las conexiones. 

La principal novedad es el es nuevo Bluetooth de baja energía (BLE) el cual optimiza el consumo de potencia para dispositivos como los relojes inteligentes, auriculares o manos libres.
 


Paso de información entre dispositivos Android


Aunque no es una novedad en sí es realmente interesante y cómodo ya que podremos tener nuestras apps al migrarnos a un nuevo dispositivo gracias a la cuenta de Google. 

Conclusión

Hay actualizaciones que cambian cosas, pero hay otras como está que innovan. Y además que llevan la experiencia de usuario hasta un alto grado de personalización, comodidad y sencillez haciendo lo sentir parte del ecosistema.