Create game Sprites with Keynote

Create game Sprites with Keynote

DBudd_Swift_Playgrounds_Screenshot.PNG

This week my students completed their Swift  Space Invaders project as a part of their Mobile Apps Development course. In this project students explore the basics of SpriteKit through developing classic games using the Swift programming language.  Whilst this course is currently being created in Xcode some of the students preferred to develop their projects using Swift Playgrounds.

Why use Swift Playgrounds over Xcode?

Swift Playgrounds gave them the ability to work on their projects while they were away from the computer lab and it was also easier to debug their code because of the speed the Swift Playgrounds renders projects.

Alien_Sprite.PNG

The students who chose to develop their projects in Swift Playgrounds were also able to experiment with developing their own Sprites using Keynote.  As I showed in a previous post you can easily create Sprites in Keynote and import them into Swift Playgrounds.

Create Space Invaders yourself in Swift Playgrounds

DBudd_Swift_Starting_Points.jpg

If you wish to start experimenting with this yourself start with a "Blank" template from the Starting Point in Swift Playgrounds on your iPad.  Once you have your blank template you can copy the code below into Swift Playgrounds and experiment with Sprites. The project starts off similar to the Colour Switch game by creating a GameScene within a View Controller and uses collision detection in a similar fashion.

The code is available below for you to re-create the project yourself, however, there are lots of modifications which could me made to improve this very simple version of the game.

import PlaygroundSupport
import SpriteKit

class GameScene: SKScene, SKPhysicsContactDelegate {
    
    let collisionBulletCategory: UInt32  = 0x1 << 0
    let collisionAlienCategory: UInt32    = 0x1 << 1
    
    let ship = SKSpriteNode(texture: SKTexture(image: #imageLiteral(resourceName: "1__#$!@%!#__PNG image.png")))
    
    func createShip(){
        ship.size = CGSize(width: 100, height: 100)
        ship.color = UIColor.blue
        ship.position = CGPoint(x: 400, y: 150)
        self.addChild(ship)
    }
    
    func createAlien(){
        
        let alien = SKSpriteNode(texture: SKTexture(image: #imageLiteral(resourceName: "PNG image.png")))
        
        alien.size = CGSize(width: 110, height: 100)
        alien.color = UIColor.green
        alien.position = CGPoint(x: 0, y: 1100)
        alien.name = "alien"
        
        alien.physicsBody?.isDynamic = true
        alien.physicsBody = SKPhysicsBody(rectangleOf: alien.frame.size)
        alien.physicsBody! .affectedByGravity = false
        alien.physicsBody!.usesPreciseCollisionDetection = true
        alien.physicsBody!.categoryBitMask = collisionAlienCategory
        alien.physicsBody!.contactTestBitMask = collisionBulletCategory
        
        self.addChild(alien)
        
        let moveLeft = SKAction.move(by: CGVector(dx: -800, dy: 0), duration: 3)
        let moveRight = SKAction.move(by: CGVector(dx: 800, dy: 0), duration: 3)
        let moveDown = SKAction.move(by: CGVector(dx: 0, dy: -100), duration: 0.1)
        
        let sequence = SKAction.sequence([moveRight, moveDown, moveLeft, moveDown])
        let repeatSequence = SKAction.repeatForever(sequence)
        alien.run(repeatSequence)
    }
    
    
    func generateAliens(){
        let actionWait = SKAction.wait(forDuration: 0.5)
        let actionRun =  SKAction.run ({
            self.createAlien()
        })
        
        let sequence = SKAction.sequence([actionWait, actionRun])
        let sequenceRepeat = SKAction.repeat(sequence, count: 18)
        
        self.run(sequenceRepeat)
    }
    
    override func didMove(to view: SKView) {
        
        self.physicsWorld.contactDelegate = self
        
        createShip()
        generateAliens()
        
        //gesture recognizer
        let directions: [UISwipeGestureRecognizerDirection] = [.right, .left, .up, .down]
        
        for direction in directions {
            let gesture = UISwipeGestureRecognizer(target: self, action: #selector(GameScene.respondToSwipeGesture(_:)))
            gesture.direction = direction
            view.addGestureRecognizer(gesture)
        }
    }
    
    func didBegin(_ contact: SKPhysicsContact) {
        contact.bodyA.node!.removeFromParent()
        contact.bodyB.node!.removeFromParent()
    }
    
    @objc func respondToSwipeGesture(_ gesture: UIGestureRecognizer) {
        if let swipeGesture = gesture as? UISwipeGestureRecognizer {
            switch swipeGesture.direction {
            case UISwipeGestureRecognizerDirection.right:
                let moveRight = SKAction.move(by: CGVector(dx: 50, dy: 0), duration: 0.1)
                ship.run(moveRight)
            case UISwipeGestureRecognizerDirection.left:
                let moveLeft = SKAction.move(by: CGVector(dx: -50, dy: 0), duration: 0.1)
                ship.run(moveLeft)
            default:
                break // should never get here.
            }
        }
    }
    
    func createBullet(){
        let bullet = SKSpriteNode()
        bullet.size = CGSize(width: 25, height: 25)
        bullet.color = UIColor.red
        bullet.position = ship.position
        bullet.name = "bullet"
        
        bullet.physicsBody = SKPhysicsBody(rectangleOf: bullet.frame.size)
        bullet.physicsBody!.isDynamic = true
        bullet.physicsBody!.affectedByGravity = false
        bullet.physicsBody!.categoryBitMask = collisionBulletCategory
        bullet.physicsBody!.contactTestBitMask = collisionAlienCategory
        bullet.physicsBody!.usesPreciseCollisionDetection = true
        
        self.addChild(bullet)
        
        let moveUp = SKAction.move(to: CGPoint(x: ship.position.x, y: 1300), duration: 2)
        bullet.run(moveUp)
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        createBullet()
    }
    
    override func update(_ currentTime: TimeInterval) {
        // Called before each frame is rendered
    }
}


let scene = GameScene(size: CGSize(width: 800, height: 1200))
scene.scaleMode = .aspectFill

let view = SKView(frame: CGRect(x:0, y:0, width: 800, height: 1200))
view.presentScene(scene)

PlaygroundPage.current.liveView = view

Want to know more?

DBUDD_Swift_Playgrounds_Mobile_App.jpg

If you wish to understand the code more then I would advise you to check out my course in iTunes U called Mobile Game Development (which is also translated into Spanish)

Makeblock Neuron with Swift Playgrounds

Makeblock Neuron with Swift Playgrounds

Map earthquake data in Swift Playgrounds

Map earthquake data in Swift Playgrounds