27
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-03-09

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


作業工程:

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

1. テキストからノードを作る!

SKViewを貼る!

まずは基礎となるSKViewを貼る。
UIViewController のview クラスをSKView に変更する。
Main.storyboardでViewを選択してFile Inspector > Identity Inspectorで変更する
Create_SKView.png

SKSceneを追加する!

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を生成して配列に入れておく

    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 は物体の摩擦力。

    @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
        }
    }

タップして実行する

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

Drop480.gif

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

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

    @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)
    }

タップして実行する

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

Impluse480.gif

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


27
19
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?