iPhone クジラキャッチ

クジラを動かして落ちてくるブロックをキャッチするiPhoneアプリのサンプルコードを描いてみます。

import UIKit

import SpriteKit

class ViewController: UIViewController, SKSceneDelegate, SKPhysicsContactDelegate {

    var scene : SKScene?

    var lasttime : NSTimeInterval?

    var movePoint : CGPoint?

    

    override func viewDidLoad() {

        super.viewDidLoad()

        setupScene()

        createWave()

        createWhale()

    }

    func setupScene() {

        let sv = SKView(frame: view.bounds)

        view.addSubview(sv)

        

        scene = {

            let s = SKScene(size: sv.frame.size)

            s.backgroundColor = UIColor(hue: 0.5, saturation: 0.1, brightness: 1, alpha: 1)

            s.delegate = self

            s.physicsWorld.contactDelegate = self

            return s

        }()

        

        sv.presentScene(scene)

    }

    func createWave() {

        let path = UIBezierPath()

        path.moveToPoint(CGPointZero)

        path.addCurveToPoint(CGPointMake(50, 0), controlPoint1: CGPointMake(25, 20), controlPoint2: CGPointMake(25, –20))

        path.addLineToPoint(CGPointMake(50, –50))

        path.addLineToPoint(CGPointMake(0, –50))

        

        for i in 020 {

            let shape = SKShapeNode(path: path.CGPath)

            shape.fillColor = UIColor(hue: 0.5, saturation: 0.5, brightness: 1, alpha: 1)

            shape.position = CGPointMake(50 * CGFloat(i), 30)

            shape.zPosition = 10

            scene?.addChild(shape)

        }

    }

    

    func createWhale() {

        let whale = SKNode()

        whale.name = “whale”

        whale.position = CGPoint(x: 100, y: 50)

        scene?.addChild(whale)

        

        

        var path = UIBezierPath()

        path.moveToPoint(CGPointZero)

        path.addCurveToPoint(CGPointMake(100, 0), controlPoint1: CGPointMake(40, 70), controlPoint2: CGPointMake(80, –40))

        path.addLineToPoint(CGPointMake(100, –40))

        path.addLineToPoint(CGPointMake(0, –40))

        let body = SKShapeNode(path: path.CGPath)

        body.fillColor = UIColor(hue: 0.55, saturation: 0.9, brightness: 1, alpha: 1)

        body.strokeColor = UIColor(hue: 0.5, saturation: 0.6, brightness: 1, alpha: 1)

        whale.addChild(body)

        

        let eye = SKShapeNode(circleOfRadius: 4)

        eye.fillColor = UIColor.blackColor()

        eye.position = CGPoint(x: 14, y: –8)

        whale.addChild(eye)

        

        path = UIBezierPath()

        path.addArcWithCenter(CGPoint(x: –50, y: 10), radius: 40, startAngle: 1.6, endAngle: 0.2, clockwise: false)

        path.closePath()

        

        for i in 01 {

            let whaleSpouts = SKShapeNode(path: path.CGPath)

            whaleSpouts.fillColor = UIColor(hue: 0.5, saturation: 0.5, brightness: 1, alpha: 1)

            whaleSpouts.strokeColor = UIColor.lightGrayColor()

            whaleSpouts.position = CGPoint(x: i == 0 ? 20 : 40, y: 10)

            if i == 0 {

                whaleSpouts.xScale = –1.0

            }

            whale.addChild(whaleSpouts)

        }

        

        let plate = SKSpriteNode(color: UIColor.whiteColor().colorWithAlphaComponent(0.3), size: CGSize(width: 80, height: 5))

        plate.position = CGPoint(x: 30, y: 60)

        plate.physicsBody = SKPhysicsBody(rectangleOfSize: plate.size)

        plate.physicsBody?.dynamic = false

        plate.physicsBody?.friction = 1.0

        plate.physicsBody?.categoryBitMask = 0x1 << 2

        plate.physicsBody?.contactTestBitMask = 0x1 << 1

        whale.addChild(plate)

        

        whale.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: 1, height: 1))

        whale.physicsBody?.mass = 1000

        whale.physicsBody?.allowsRotation = false

    }

    

    func update(currentTime: NSTimeInterval, forScene scene: SKScene) {

        

        // create box

        if let lasttime = self.lasttime {

            let dt = currentTime – lasttime

            if dt > 3.0 {

                let box = SKSpriteNode(color: UIColor(hue: 0.1 * CGFloat(currentTime % 10), saturation: 0.6, brightness: 1, alpha: 1), size: CGSize(width: 50, height: 20))

                box.name = “box”

                box.position = CGPoint(x: CGFloat(currentTime % 10) *  50, y: 300)

                scene.addChild(box)

                box.physicsBody = SKPhysicsBody(rectangleOfSize: box.size)

                box.physicsBody?.dynamic = true

                box.physicsBody?.collisionBitMask = 0x1 << 2

                box.physicsBody?.contactTestBitMask = 0x1 << 2

                self.lasttime = currentTime

            }

        } else {

            self.lasttime = currentTime

        }

        

        

        // speed

        scene.children

            .filter { ($0 as! SKNode).name == “box” }

            .map { n -> Void in

                (n as! SKNode).physicsBody?.velocity = CGVector(dx: 0, dy: 2)

            }

        

        if let whale = scene.childNodeWithName(“whale”) {

            if whale.position.y < 45 {

                whale.physicsBody?.velocity = CGVector(dx: 0, dy: 60)

            } else {

                whale.physicsBody?.velocity = CGVector(dx: 0, dy: 20)

            }

            

        if let p = self.movePoint {

            let dx = p.x – whale.position.x

            if dx > 10 {

                whale.physicsBody?.velocity = CGVector(dx: 40, dy: whale.physicsBody!.velocity.dy)

            } else if dx < –10 {

                whale.physicsBody?.velocity = CGVector(dx: –40, dy: whale.physicsBody!.velocity.dy)

            }

        }}

    }

    

    func didBeginContact(contact: SKPhysicsContact) {

        if let whale = self.scene?.childNodeWithName(“whale”) {

        

            ([contact.bodyA, contact.bodyB] as [SKPhysicsBody])

                .filter { $0.node?.name == “box” }

                .map { n -> Void in

                    n.node?.name = “”

                    let j = SKPhysicsJointFixed.jointWithBodyA(whale.physicsBody, bodyB: n, anchor: n.node!.position)

                    self.scene?.physicsWorld.addJoint(j)

            }

        }

    }

    

    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {

        if let touch = touches.first as? UITouch {

            self.movePoint = touch.locationInNode(self.scene)

        }

    }

}