<file_sep>//
//  MenuScene.swift
//  Experiments
//
//  Created by <NAME> on 8/1/15.
//  Copyright © 2015 <NAME>. All rights reserved.
//

import Foundation
import SpriteKit

class MenuScene: SKScene {
/*

    required init?(coder aDecoder: NSCoder) {
        fatalError("not initiliased")
    }
    
    override init(size: CGSize) {
        super.init(size: size)
        
        let playLabel = SKLabelNode(text: "TAP TO PLAY")
        playLabel.position = CGPointMake(size.width/2, 100)
        playLabel.fontSize = 20
        playLabel.fontName = "Helvetica"
        addChild(playLabel)
    }
    
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        
        let scene = GameScene(size: (view?.bounds.size)!)
        scene.scaleMode = .AspectFill
        view?.presentScene(scene, transition: SKTransition.crossFadeWithDuration(0.5))
    }
*/
    
    var startButton: SKSpriteNode!
    var scoreButton: SKSpriteNode!
    var aboutButton: SKSpriteNode!
    var scoreNode: SKLabelNode!
    var highlightAction: SKAction!
    
    let texturesAtlas = SKTextureAtlas(named: "sprites.atlas")
    
    override init(size: CGSize) {
        super.init(size: size)
        
        let backgroundNode = SKSpriteNode(imageNamed: "background0")
        backgroundNode.position = CGPointMake(size.width/2, 0)
        backgroundNode.anchorPoint = CGPointMake(0.5, 0.35)
        addChild(backgroundNode)
        
        
        startButton = SKSpriteNode(texture: texturesAtlas.textureNamed("start"))
        startButton.position = CGPointMake(size.width/2, size.height*0.8)
        addChild(startButton)
        
        scoreButton = SKSpriteNode(texture: texturesAtlas.textureNamed("highscore"))
        scoreButton.position = CGPointMake(size.width/2, startButton.position.y - 100)
        addChild(scoreButton)
        
        aboutButton = SKSpriteNode(texture: texturesAtlas.textureNamed("about"))
        aboutButton.position = CGPointMake(size.width/2, scoreButton.position.y - 100)
        addChild(aboutButton)
        
        
        scoreNode = SKLabelNode(text: "**1000**")
        scoreNode.position = CGPointMake(size.width/2, size.height*0.9)
        scoreNode.fontSize = 40
        scoreNode.hidden = true
        addChild(scoreNode)
        
        highlightAction = SKAction.scaleXTo(1.2, duration: 0.3)
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
    override func didMoveToView(view: SKView) {
        
    }
    
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        
        let touch = touches.first!
        let touchLocation = touch.locationInNode(self)
        
        if CGRectContainsPoint(startButton.frame, touchLocation){
            
            let scene = GameScene(size: (self.view?.bounds.size)!)
            scene.scaleMode = .AspectFill
            startButton.runAction(highlightAction, completion: {
                self.view?.presentScene(scene, transition: SKTransition.crossFadeWithDuration(0.5))
            })
            
        }else if CGRectContainsPoint(scoreButton.frame, touchLocation){
            scoreNode.hidden = false
        }
    }
    
    override func update(currentTime: NSTimeInterval) {
        
    }
}
<file_sep>//
//  VortexNode.swift
//  Experiments
//
//  Created by <NAME> on 8/1/15.
//  Copyright © 2015 <NAME>. All rights reserved.
//

import SpriteKit

class VortexNode: SKSpriteNode {
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(code:) not implemented")
    }
    
    init(textureAtlas: SKTextureAtlas){
        
        let frame0 = textureAtlas.textureNamed("BlackHole0")
        let frame1 = textureAtlas.textureNamed("BlackHole1")
        let frame2 = textureAtlas.textureNamed("BlackHole2")
        let frame3 = textureAtlas.textureNamed("BlackHole3")
        let frame4 = textureAtlas.textureNamed("BlackHole4")
        
        let textures = [frame0, frame1, frame2, frame3, frame4]
        let animation = SKAction.animateWithTextures(textures, timePerFrame: 0.2)
        let rotateAction = SKAction.repeatActionForever(animation)
        
        super.init(texture: frame0, color: UIColor.clearColor(), size: frame0.size())
        
        self.name = vortexNodeName
        self.physicsBody = SKPhysicsBody(circleOfRadius: self.size.width/2)
        self.physicsBody?.dynamic = false
        self.physicsBody?.linearDamping = 1.0
        self.physicsBody?.collisionBitMask = 0
        self.physicsBody?.categoryBitMask = CollisionCategoryObstacle
        self.physicsBody?.contactTestBitMask = CollisionCategoryPlayer
        self.physicsBody?.allowsRotation = false
        
        self.runAction(rotateAction)
    }
}
<file_sep>//
//  PlayerNode.swift
//  Experiments
//
//  Created by <NAME> on 8/1/15.
//  Copyright © 2015 <NAME>. All rights reserved.
//

import SpriteKit

class PlayerNode: SKSpriteNode {
    
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(code:) not implemented")
    }
    
    init(textureAtlas: SKTextureAtlas){
        let texture = textureAtlas.textureNamed("ship")
        super.init(texture: texture, color: UIColor.clearColor(), size: texture.size())
        
        self.name = playerNodeName
        self.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(30, 65))
        self.physicsBody?.dynamic = false
        self.physicsBody?.affectedByGravity = false
        self.physicsBody?.linearDamping = 1.0
        self.physicsBody?.allowsRotation = false
        self.physicsBody?.collisionBitMask = CollisionCategoryBoundary
        self.physicsBody?.categoryBitMask = CollisionCategoryPlayer
        self.physicsBody?.contactTestBitMask = CollisionCategoryOrb | CollisionCategoryObstacle | CollisionCategoryBoundary
    }
}
<file_sep>//
//  GameScene.swift
//  Experiments
//
//  Created by <NAME> on 8/1/15.
//  Copyright (c) 2015 <NAME>. All rights reserved.
//

import SpriteKit
import CoreMotion
import AVFoundation

class GameScene: SKScene, SKPhysicsContactDelegate {
    
    //game state
    enum GameState: Int {
        case Starting
        case Playing
        case Ended
    }
    var gameState:GameState = .Starting
    
    //world
    var game_floor: CGFloat!
    
    //timing
    var delta_t = NSTimeInterval(0)
    var last_update_t = NSTimeInterval(0)
    
    //textures
    var texturesAtlas: SKTextureAtlas!
    
    //player
    var playerNode: SKSpriteNode!
    var exhaustNode: SKEmitterNode!
    
    //sounds
    var tapSound: SKAction!
    var orbSound: SKAction!
    var gameoverSound: SKAction!
    
    //background
    var backgroundNode: SKNode!
    var backgroundNode0: SKSpriteNode!
    var backgroundNode1: SKSpriteNode!
    var backgroundNode2: SKSpriteNode!
    let background_velocity = 100.0
    var firstTileRemoved = false
    
    
    // Score
    var score = 0 {
        didSet {
            label_score.text = "\(score)"
        }
    }
    var label_score: SKLabelNode!
    
    // Instructions
    var instructions: SKSpriteNode!
    var restartLabel: SKLabelNode!
    
    
    override func didMoveToView(view: SKView) {
        
        backgroundColor = UIColor.blackColor()
        
        texturesAtlas = SKTextureAtlas(named: "sprites.atlas")
        
        initWorld()
        initBackground()
        initPlayer()
        initHUD()
        initSounds()
        
    }
    
    
    //MARK: - world
    func initWorld(){
        
        game_floor = frame.size.height * 0.15
        physicsBody = SKPhysicsBody(edgeLoopFromRect: CGRectMake(0, game_floor, size.width, size.height - game_floor))
        physicsBody?.categoryBitMask = CollisionCategoryBoundary
        physicsWorld.gravity = CGVectorMake(0, -5)
        physicsWorld.contactDelegate = self
        
    }
    
    
    //MARK: - sounds
    func initSounds(){
        tapSound = SKAction.playSoundFileNamed("beep.mp3", waitForCompletion: false)
        orbSound = SKAction.playSoundFileNamed("beep2.mp3", waitForCompletion: false)
        gameoverSound = SKAction.playSoundFileNamed("gameover.mp3", waitForCompletion: false)
    }
    
    
    //MARK: - HUD
    func initHUD() {
        
        label_score = SKLabelNode(fontNamed:"MarkerFelt-Wide")
        label_score.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMaxY(frame) - 100)
        label_score.text = "0"
        label_score.zPosition = 50
        addChild(label_score)
        
        instructions = SKSpriteNode(imageNamed: "tap")
        instructions.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMidY(frame) - 10)
        instructions.zPosition = 50
        
        let animate = SKAction.sequence([SKAction.scaleBy(0.8, duration: 0.3), SKAction.scaleBy(1.25, duration: 0.3)])
        instructions.runAction(SKAction.repeatActionForever(animate), withKey: "instructions_animation")
        addChild(instructions)
    }
    
    
    //MARK: - player
    func initPlayer(){
    
        playerNode = PlayerNode(textureAtlas: texturesAtlas)
        playerNode.position = CGPointMake(CGRectGetMidX(frame), 130)
        playerNode.zPosition = 20
        
        
        exhaustNode = SKEmitterNode(fileNamed: "Exhaust")
        exhaustNode.position = CGPointMake(0, -playerNode.size.height/2)
        exhaustNode.zPosition = 23
        exhaustNode.hidden = true
        playerNode.addChild(exhaustNode)
        
        addChild(playerNode)
    }
    
    func movePlayer(){
        
        playerNode.physicsBody?.applyImpulse(CGVectorMake(0, 35))
        runAction(tapSound)
        exhaustNode.resetSimulation()
    }
    
    
    //MARK: - obstacles
    func initLaser(){
        var duration = ((Double(arc4random() % 32) / 16.0)) * 1
        if duration < 0.4 {
            duration = 0.4
        }
        
//        let laserLeft = SKSpriteNode(color: UIColor.redColor(), size: CGSizeMake(size.width/2, 20))
        let laserLeft = SKSpriteNode(imageNamed: "laser")
        laserLeft.name = "laser"
        laserLeft.anchorPoint = CGPointMake(1, 0.5)
        laserLeft.position = self.convertPoint(CGPointMake(0, size.height + laserLeft.size.height), toNode: backgroundNode)
        laserLeft.physicsBody = SKPhysicsBody(rectangleOfSize: laserLeft.frame.size, center: CGPointMake(-laserLeft.size.width / 2, 0))
        laserLeft.zPosition = 50
        
        laserLeft.physicsBody?.dynamic = false
        laserLeft.physicsBody?.categoryBitMask = CollisionCategoryObstacle
        laserLeft.physicsBody?.collisionBitMask = 0
        
        let laserRight = SKSpriteNode(imageNamed: "laser")
        laserRight.name = "laser"
        laserRight.anchorPoint = CGPointMake(0, 0.5)
        laserRight.position = self.convertPoint(CGPointMake(size.width, size.height + laserRight.size.height), toNode: backgroundNode)
        laserRight.zPosition = 50
        
        laserRight.physicsBody = SKPhysicsBody(rectangleOfSize: laserRight.frame.size, center: CGPointMake(laserRight.size.width / 2, 0))
        laserRight.physicsBody?.dynamic = false
        laserRight.physicsBody?.categoryBitMask = CollisionCategoryObstacle
        laserRight.physicsBody?.collisionBitMask = 0
        
        let leftAction = SKAction.sequence([SKAction.moveToX(size.width/2, duration: duration), SKAction.moveToX(0, duration: duration)])
        
        let rightAction = SKAction.sequence([SKAction.moveToX(size.width/2, duration: duration), SKAction.moveToX(size.width, duration: duration)])
        
        laserLeft.runAction( SKAction.sequence([SKAction.repeatActionForever(leftAction), SKAction.runBlock({ /*laserLeft.removeFromParent()*/ }) ]) , withKey: "laserAction")
        
        laserRight.runAction( SKAction.sequence([SKAction.repeatActionForever(rightAction), SKAction.runBlock({ /*laserRight.removeFromParent()*/ }) ]), withKey: "laserAction")
        
        
        let orb = OrbNode(textureAtlas: texturesAtlas)
        orb.position = self.convertPoint(CGPointMake(size.width/2, size.height + laserLeft.size.height), toNode: backgroundNode)
        orb.name = "orb"
        
        
        let animate = SKAction.sequence([SKAction.scaleBy(0.8, duration: 0.3), SKAction.scaleBy(1.25, duration: 0.3)])
        orb.runAction(SKAction.repeatActionForever(animate), withKey: "orb_animation")
        
        backgroundNode.addChild(orb)
        backgroundNode.addChild(laserLeft)
        backgroundNode.addChild(laserRight)
    }
    
    func removeLasers(){
        backgroundNode.enumerateChildNodesWithName("laser") { (node, stop) -> Void in
            
            let laser_position = self.backgroundNode.convertPoint(node.position, toNode: self)
            
            if laser_position.y < -40 {
                node.removeActionForKey("laserAction")
                node.removeFromParent()
            }
        }
    }
    
    
    //MARK: - background
    func initBackground(){
        backgroundNode = SKNode()
        addChild(backgroundNode)
        
        backgroundNode0 = SKSpriteNode(imageNamed: "background0")
        backgroundNode0.anchorPoint = CGPointMake(0.5, 0)
        backgroundNode0.position = CGPointMake(size.width/2, 0)
        backgroundNode.addChild(backgroundNode0)
        
        backgroundNode1 = SKSpriteNode(imageNamed: "background1")
        backgroundNode1.anchorPoint = CGPointMake(0.5, 0)
        backgroundNode1.position = CGPointMake(size.width/2, backgroundNode0.size.height)
        backgroundNode1.name = "bg_tile"
        backgroundNode.addChild(backgroundNode1)
        
        backgroundNode2 = SKSpriteNode(imageNamed: "background1")
        backgroundNode2.anchorPoint = CGPointMake(0.5, 0)
        backgroundNode2.position = CGPointMake(size.width/2, backgroundNode0.size.height + backgroundNode1.size.height)
        backgroundNode2.name = "bg_tile"
        backgroundNode.addChild(backgroundNode2)
    }
    
    func moveBackground(){
        
        let delta_y = -1 * background_velocity * delta_t
        
        backgroundNode.position = CGPointMake(backgroundNode.position.x, backgroundNode.position.y + CGFloat(delta_y))
        
        if firstTileRemoved == false && backgroundNode0.position.y < -backgroundNode0.size.height {
            firstTileRemoved = true
            backgroundNode0.removeFromParent()
        }
        
        backgroundNode.enumerateChildNodesWithName("bg_tile") { (node, stop) -> Void in
            
            let background_position = self.backgroundNode.convertPoint(node.position, toNode: self)
            
            if background_position.y < -node.frame.size.height {
                node.position = self.convertPoint(CGPointMake(self.size.width/2, node.frame.size.height), toNode: self.backgroundNode)
            }
        }
        
    }
    
    
    
    //MARK: - touchcontrol
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        
        if gameState == .Starting {
            
            instructions.hidden = true
            instructions.removeActionForKey("instructions_animation")
            gameState = .Playing
            playerNode.physicsBody?.dynamic = true
            playerNode.physicsBody?.affectedByGravity = true
            
            exhaustNode.hidden = false
            
            
            let addLaserAction = SKAction.runBlock({ self.initLaser() })
            runAction(SKAction.repeatActionForever(SKAction.sequence([SKAction.waitForDuration(2), addLaserAction ])))
            
            movePlayer()
            
        }else if gameState == .Playing {
            
            movePlayer()
        }
        else if gameState == .Ended {
            let touchLocation = touches.first?.locationInNode(self)
            if nodeAtPoint(touchLocation!) == playerNode {
                restartGame()
            }
        }
    }
    
    func gameOver(){
        
        gameState = .Ended

        playerNode.physicsBody?.categoryBitMask = 0
        playerNode.physicsBody?.collisionBitMask = CollisionCategoryBoundary
        
        restartLabel = SKLabelNode(fontNamed: "MarkerFelt-Wide")
        restartLabel.text = "TAP SHIP TO PLAY"
        restartLabel.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMidY(frame) - 100)
        restartLabel.zPosition = 50
        addChild(restartLabel)
        
//        NSTimer.scheduledTimerWithTimeInterval(4.0, target: self, selector: Selector("restartGame"), userInfo: nil, repeats: false)
    }
    
    
    func restartGame() {
        
        
        let scene = GameScene(size: (self.view?.bounds.size)!)
        scene.scaleMode = .AspectFill
        view?.presentScene(scene, transition: SKTransition.crossFadeWithDuration(0.5))
//        gameState = .Starting
//        playerNode.removeFromParent()
//        backgroundNode.removeAllChildren()
//        backgroundNode.removeFromParent()
//        
//        // 6
//        instructions.hidden = false
//        removeAllActions()
//        
//        
//        score = 0
//        label_score.text = "0"
        
    }

    func didBeginContact(contact: SKPhysicsContact) {
        
        
        let collision:UInt32 = (contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask)
        
        
        if collision == (CollisionCategoryPlayer | CollisionCategoryOrb) {
            score++
            label_score.text = "\(score)"
            runAction(orbSound)
            contact.bodyB.node?.removeAllActions()
            contact.bodyB.node?.removeFromParent()
        }
        
        // 2
        if collision == (CollisionCategoryPlayer | CollisionCategoryObstacle) {
            gameOver()
        }
        
        // 3
        if collision == (CollisionCategoryPlayer | CollisionCategoryBoundary) {
            print("collide")
            gameOver()
            playerNode.runAction(SKAction.rotateToAngle(CGFloat(M_PI/2), duration: 0.5))
//            if bird.position.y < 150 {
//            }
        }
    }
    
    //MARK: - update loop
    override func update(currentTime: NSTimeInterval) {
        
        delta_t = last_update_t == 0 ? 0 : currentTime - last_update_t
        last_update_t = currentTime
        
        if gameState == .Playing {
            moveBackground()
            removeLasers()
            
            if playerNode.physicsBody?.velocity.dy > 300{
                playerNode.physicsBody?.velocity.dy = 300
            }
        }
    }
    
    //MARK: - deinitialisation
    deinit{
        
    }
}<file_sep>//
//  OrbNode.swift
//  Experiments
//
//  Created by <NAME> on 8/1/15.
//  Copyright © 2015 <NAME>. All rights reserved.
//

import SpriteKit

class OrbNode: SKSpriteNode {
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(code:) not implemented")
    }
    
    init(textureAtlas: SKTextureAtlas){
        let texture = textureAtlas.textureNamed("cell")
        super.init(texture: texture, color: UIColor.clearColor(), size: texture.size())
        
        self.name = orbNodeName
//        self.physicsBody = SKPhysicsBody(circleOfRadius: self.size.width/2)
        self.physicsBody = SKPhysicsBody(rectangleOfSize: CGRectMake(0.0, 0.0, 20.0, 37.0).size)
        self.physicsBody?.dynamic = false
        self.physicsBody!.categoryBitMask = CollisionCategoryOrb
        self.physicsBody?.contactTestBitMask = CollisionCategoryPlayer
        self.physicsBody!.collisionBitMask = 0
    }
}
<file_sep>//
//  SharedConstants.swift
//  Experiments
//
//  Created by <NAME> on 8/1/15.
//  Copyright © 2015 <NAME>. All rights reserved.
//

import Foundation

let playerNodeName = "PLAYER_NODE"
let orbNodeName = "ORB_NODE"
let vortexNodeName = "VORTEX_NODE"

let CollisionCategoryPlayer: UInt32 = 0x1 << 1
let CollisionCategoryOrb: UInt32 = 0x1 << 2
let CollisionCategoryObstacle: UInt32 = 0x1 << 3
let CollisionCategoryBoundary: UInt32 = 0x1 << 3<file_sep>//
//  GameViewController.swift
//  Experiments
//
//  Created by <NAME> on 8/1/15.
//  Copyright (c) 2015 <NAME>. All rights reserved.
//

import UIKit
import SpriteKit
import GoogleMobileAds

class GameViewController: UIViewController, GADInterstitialDelegate, GADBannerViewDelegate {
//    
    @IBOutlet weak var bannerView: GADBannerView!
//    var interstitial: GADInterstitial!

    override func viewDidLoad() {
        super.viewDidLoad()
        

        // Configure the view.
        let skView = self.view as! SKView
        skView.showsFPS = true
        skView.showsNodeCount = true
//        skView.showsPhysics = true
        
        /* Sprite Kit applies additional optimizations to improve rendering performance */
//          skView.ignoresSiblingOrder = true
        
        
        self.bannerView.adUnitID = "ca-app-pub-3940256099942544/2934735716"
        self.bannerView.rootViewController = self
        bannerView.delegate = self
        let request = GADRequest();
        request.testDevices = [kGADSimulatorID]
        self.bannerView.loadRequest(GADRequest())
        
        let scene = GameScene(size: (self.view?.bounds.size)!)
        scene.scaleMode = .AspectFill
        skView.presentScene(scene)
        
        
//        NSNotificationCenter.defaultCenter().addObserver(self, selector: "appWillEnterBackground", name: "interruptGame", object: nil)
        
    }
    
    
    

//    override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
//        if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
//            return .AllButUpsideDown
//        } else {
//            return .All
//        }
//    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Release any cached data, images, etc that aren't in use.
    }

    override func prefersStatusBarHidden() -> Bool {
        return true
    }
}
