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

Intro to Sprite Kit

Giovanni Cortes
May 18, 2016
170

Intro to Sprite Kit

Introduccion a Sprite Kit

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