[Swift3.0][iOS][SpriteKit]SpriteKitでテキストを落としたり、ぶっ飛ばしたりした！

SpriteKitフレームワークを使って文字からラベルを作り、重力や力を加えたりしてインタラクションなアニメーションを作ります。

---
作業工程:
1. テキストからノードを作る！
　- SKViewを貼る！
　- SKSceneを追加する！
　- 素材となるテキストからノードを作る！
2. 突然重力を与えて落とす！
3. ランダムな方向にぶっ飛ばす！

---

# 1. テキストからノードを作る！
## SKViewを貼る！

まずは基礎となるSKViewを貼る。
UIViewController のview クラスをSKView に変更する。
Main.storyboardでViewを選択してFile Inspector > Identity Inspectorで変更する
![Create_SKView.png](https://qiita-image-store.s3.amazonaws.com/0/156085/ef2ca276-a5df-35a1-effd-7ce9901d44ef.png)

## SKSceneを追加する！

```swift
import UIKit
import SpriteKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let skView = self.view as! SKView
        let scene = HelloScene(size: skView.bounds.size)
        skView.presentScene(scene)
        
        skView.showsFPS = true
        skView.showsNodeCount = true
    }
}
```

## 素材となるテキストからノードを作る！
定義したテキストからSKLabelNodeを生成して配列に入れておく

```swift
    fileprivate func initializeContent() {
        guard let view = view else {
            return
        }
        
        self.physicsBody = SKPhysicsBody(edgeLoopFrom:CGRect(x: 0, y: 200.0, width: self.size.width, height: 200.0))
        self.physicsBody?.categoryBitMask = 0x1 << 1
        self.physicsBody?.contactTestBitMask = 0x1 << 0
        self.physicsBody?.collisionBitMask = 0xFFFFFFFF
        
        let helloText = "Hello Everyone!"
        
        for (idx, character) in helloText.characters.enumerated() {
            let fontSize: CGFloat = 44.0
            let positionX = (view.bounds.size.width - fontSize * CGFloat(helloText.characters.count)) / 2.0 + fontSize * CGFloat(idx)
            let labelNode = SKLabelNode(text:String(character))
            labelNode.fontName = "AvenirNext-Bold"
            labelNode.fontColor = UIColor(red: 131.0/255, green: 204.0/255, blue: 212.0/255, alpha: 1.0)
            labelNode.fontSize = fontSize
            labelNode.position = CGPoint(x:positionX, y:view.bounds.midY + 200.0)
            labelNode.alpha = 1.0
            self.addChild(labelNode)
            helloLabelNodes.append(labelNode)
        }
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapGesture(_:)))
        view.addGestureRecognizer(tapGestureRecognizer)
    }
```

# 2. 突然重力を与えて落とす！

restitution は物体の反発力、
friction は物体の摩擦力。

```swift
    @objc fileprivate func applyPhysicsBody() {
        helloLabelNodes.forEach {
            $0.physicsBody = SKPhysicsBody(rectangleOf:$0.frame.size, center:CGPoint(x:0, y:$0.frame.size.height / 2.0))
            $0.physicsBody?.isDynamic = true
            $0.physicsBody?.restitution = 0.6
            $0.physicsBody?.allowsRotation = true
            $0.physicsBody?.friction = 0.4
            $0.physicsBody?.categoryBitMask = 0x1 << 0
            $0.physicsBody?.contactTestBitMask = 0x1 << 1
            $0.physicsBody?.collisionBitMask = 0xFFFFFFFF
        }
    }
```

タップして実行する

```swift
    @objc fileprivate func tapGesture(_ gestureRecognizer: UITapGestureRecognizer) {
        self.applyPhysicsBody()
    }
```

![Drop480.gif](https://qiita-image-store.s3.amazonaws.com/0/156085/a2999326-597f-f4b7-4a85-18a42149cd58.gif)


# 3. ランダムな方向にぶっ飛ばす！

１文字づつランダムな角度と一定速度の力を与えるCGVector をセットする

```swift
    @objc fileprivate func applyRandomImpluse() {
        helloLabelNodes.forEach {
            var angle: CGFloat = 0
            var value: CGFloat = 0
            var vector: CGVector?
            
            $0.physicsBody = SKPhysicsBody(rectangleOf:$0.frame.size, center:CGPoint(x:0, y:$0.frame.size.height / 2.0))
            $0.physicsBody?.isDynamic = true
            $0.physicsBody?.restitution = 0.6
            $0.physicsBody?.allowsRotation = true
            $0.physicsBody?.friction = 0.4
            $0.physicsBody?.categoryBitMask = 0x1 << 0
            $0.physicsBody?.contactTestBitMask = 0x1 << 1
            $0.physicsBody?.collisionBitMask = 0xFFFFFFFF
            
            angle = self.randomFloatValue(0, high: 360) * CGFloat.pi / 180.0
            value = 50.0
            vector = CGVector(dx: (value * CGFloat(cos(Double(angle)))), dy: (value * CGFloat(sin(Double(angle)))))
            $0.physicsBody?.applyImpulse(vector!)
        }
    }

    fileprivate func randomFloatValue(_ low: CGFloat, high: CGFloat) -> CGFloat {
        return ((CGFloat(arc4random()) / CGFloat(RAND_MAX)) * (high - low) + low)
    }
```

タップして実行する

```swift
    @objc fileprivate func tapGesture(_ gestureRecognizer: UITapGestureRecognizer) {
        self.applyRandomImpluse()
    }
```

![Impluse480.gif](https://qiita-image-store.s3.amazonaws.com/0/156085/bf03151b-32a4-643b-cb00-d49d3e067ea3.gif)

決して、人名などでは行わないようにしましょう^_^
おしまい。

---