Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Intro to Sprite Kit

Avatar for Giovanni Cortes Giovanni Cortes
May 18, 2016
270

Intro to Sprite Kit

Introduccion a Sprite Kit

Avatar for Giovanni Cortes

Giovanni Cortes

May 18, 2016
Tweet

Transcript

  1. Sprite Kit Es un framework creado por Apple para crear

    videojuegos 2D que sean de alto rendimiento y que además ahorren batería.
  2. Ventajas de Sprite Kit • Creado nativamente para iOS •

    Fácil de aprender • Fue creado por Apple • Es gratis
  3. Desventajas de Sprite Kit • Solo para plataformas Apple •

    Un diseñador de escenas no tan potente • No tan poderoso como otros frameworks multiplataformas • Solo 2D
  4. Configurar nuestro ViewController para usar Sprite Kit import UIKit import

    SpriteKit class GameViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let scene = GameScene(size: view.bounds.size) let skView = view as! SKView skView.showsFPS = true skView.showsNodeCount = true skView.ignoresSiblingOrder = true scene.scaleMode = .ResizeFill skView.presentScene(scene) } override func prefersStatusBarHidden() -> Bool { return true } }
  5. Agregando nuestro sprite principal import SpriteKit class GameScene: SKScene {

    // Creamos una constante donde guardaremos nuestro sprite de la nave. // Crear el sprite es fácil, solamente pasamos el nombre de la imagen // a usar let player = SKSpriteNode(imageNamed: "Spaceship") override func didMoveToView(view: SKView) { // Ponemos el fondo en negro backgroundColor = SKColor.blackColor() // Escalamos el sprite para que no sea tan grande player.xScale = 0.2 player.yScale = 0.2 // El sprite irá al inicio en el fondo y centrado player.position = CGPoint(x: size.width * 0.5, y: size.height * 0.1) // Agregamos el sprite a la escena, ya que si no lo hacemos no aparece addChild(player) } }
  6. Agregando enemigos a nuestra escena func random() -> CGFloat {

    return CGFloat(Float(arc4random()) / 0xFFFFFFFF ) } func random(min min: CGFloat, max: CGFloat) -> CGFloat { return random() * (max - min) + min }
  7. func addEnemy() { // Creamos el sprite let enemy =

    SKSpriteNode(imageNamed: "EnemyShip") // Necesitamos escalar a los enemigos para que no sean tan grandes enemy.xScale = 0.5 enemy.yScale = 0.5 // Determinamos en donde va a aparecer el enemigo en el eje X let actualX = random(min: enemy.size.width / 2, max: size.width - enemy.size.width / 2) // Posicionamos al enemigo un poco atrás de la pantalla para que se vea que vienen de arriba // y ponemos en X lo que calculamos arriba enemy.position = CGPoint(x: actualX, y: size.height + enemy.size.height / 2) // Agregamos el enemigo a la escena addChild(enemy) // Determinamos la velocidad del enemigo let actualDuration = random(min: CGFloat(2.0), max: CGFloat(4.0)) // Creamos las acciones let actionMove = SKAction.moveTo(CGPoint(x: actualX, y: -enemy.size.height / 2), duration: NSTimeInterval(actualDuration)) let actionMoveDone = SKAction.removeFromParent() enemy.runAction(SKAction.sequence([actionMove, actionMoveDone])) }
  8. Agregando los enemigos en didMoveToView() // Acción para que aparezcan

    los enemigos indefinidamente runAction(SKAction.repeatActionForever( SKAction.sequence([ SKAction.runBlock(addEnemy), SKAction.waitForDuration(1.0) ]) ))
  9. Cámara, Action! • Un objeto SKAction es una acción que

    se ejecuta en un nodo de una escena • A menudo se usan para cambiar la posición, rotación o escala • Algunos solo pueden ser usados en objetos SKSpriteNode
  10. Acciones hijos de acciones • Secuencia de Acciones, cada acción

    inicia cuando la anterior termina • Grupo de acciones, cada acción es ejecutada al mismo tiempo que las otras acciones • Repetición de acciones, cuando una acción se completa, se repite de nuevo
  11. // Creamos una cola de taps para saber si hemos

    disparado o no var tapQueue = [Int]() func fireBullet() { // Creamos el sprite del laser let bullet = SKSpriteNode(imageNamed: "LaserGreen") // El laser debe salir de en medio de nuestra nave bullet.position = CGPoint(x: player.position.x, y: player.position.y + player.frame.size.height - bullet.frame.size.height / 2) // Agregamos el laser a nuestra escena addChild(bullet) // El laser va del fondo hacia arriba let actionMove = SKAction.moveTo(CGPoint(x: player.position.x, y: frame.size.height + bullet.frame.size.height / 2), duration: 1.0) let actionDone = SKAction.removeFromParent() bullet.runAction(SKAction.sequence([ actionMove, // No queremos que el usuario tire laseres indefinidamente, solo debe haber a lo mucho tres laseres por cada 60 segundos SKAction.waitForDuration(3.0 / 60.0), actionDone ])) }
  12. override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { if let

    touch = touches.first { if touch.tapCount == 1 { tapQueue.append(1) } } } func processUserTapsForUpdate(currentTime: CFTimeInterval) { for tapCount in tapQueue { // Queremos que solo sea un tap, no deseamos que la aplicación confunda con doble taps if tapCount == 1 { fireBullet() } tapQueue.removeAtIndex(0) } } // Usamos el método update para que cada vez que se produzca el loop solamente podamos hacer // a lo mucho tres disparos override func update(currentTime: NSTimeInterval) { processUserTapsForUpdate(currentTime) }
  13. ¡Colisiones! • Necesitamos un mundo físico • Crear cuerpos físicos

    para los sprites • Poner una categoría a cada sprite • Poner un delegado que se encargue del contacto
  14. Creando las categorías // Creamos las categorias de los sprites

    struct PhysicsCategory { static let None : UInt32 = 0 static let All : UInt32 = UInt32.max static let Enemy : UInt32 = 0b1 static let Laser : UInt32 = 0b10 }
  15. Actualizamos didMoveToView() // Agregamos las físicas, no hay gravedad en

    el mundo y el delegado es la escena physicsWorld.gravity = CGVectorMake(0, 0) physicsWorld.contactDelegate = self
  16. Física a los enemigos // Agregamos las físicas el enemigo

    enemy.physicsBody = SKPhysicsBody(rectangleOfSize: enemy.size) enemy.physicsBody?.dynamic = true enemy.physicsBody?.categoryBitMask = PhysicsCategory.Enemy enemy.physicsBody?.contactTestBitMask = PhysicsCategory.Laser enemy.physicsBody?.collisionBitMask = PhysicsCategory.None
  17. Física al láser bullet.physicsBody = SKPhysicsBody(rectangleOfSize: bullet.size) bullet.physicsBody?.dynamic = true

    bullet.physicsBody?.categoryBitMask = PhysicsCategory.Laser bullet.physicsBody?.contactTestBitMask = PhysicsCategory.Enemy bullet.physicsBody?.collisionBitMask = PhysicsCategory.None bullet.physicsBody?.usesPreciseCollisionDetection = true
  18. Implementando el delegado func didBeginContact(contact: SKPhysicsContact) { var firstBody: SKPhysicsBody

    var secondBody: SKPhysicsBody if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask { firstBody = contact.bodyA secondBody = contact.bodyB } else { firstBody = contact.bodyB secondBody = contact.bodyA } if ((firstBody.categoryBitMask & PhysicsCategory.Enemy != 0) && (secondBody.categoryBitMask & PhysicsCategory.Laser != 0)) { laserDidCollideWithEnemy(firstBody.node as! SKSpriteNode, enemy: secondBody.node as! SKSpriteNode) } }
  19. Retos • Mover la nave con el giroscopio • Agregar

    sonido del láser • Agregar score • Si un enemigo colisiona con la nave pierde