【Swift】SpriteKitの使い方。物理ボディを不規則な方向に揺らす。(Swift 2.2、XCode 7.3)
Noise Fieldとは
本記事では、SKFieldNodeの「Noise Field(以下、ノイズノード)」について説明する。
ノイズノードとは、物理ボディを不規則な方向に揺らすノードである。物理ボディが運動していなくても常に揺らす力が働く。
ノイズノードを使ってみる
実際にノイズノードをシーンに配置して物理ボディを揺らしてみよう。以降の手順を行う前のXcodeプロジェクトをGitHubに置いたので、試してみる方はご利用下さい。⇒「テスト用プロジェクト」
事前準備では2匹のホタルをシーンに追加しておいた。この段階では何も起きない。
下図赤枠のSKSファイルを選択してシーンエディタを開く。黄緑枠のオブジェクトライブラリボタンを押して部品一覧を表示し、ドラッグ&ドロップで「Noise Field」をシーンに配置する(紫矢印)。
黄枠のアトリビュートインスペクタボタンを押して設定画面を表示し、Nameに「noise」、Category Maskに「1」、Enabledのチェックを外す。
ホタルの画像を選択、下図赤枠のアトリビュートインスペクタボタンを押して設定画面を表示し、Field Maskに「1」を入力する。もう1匹のホタルも同じようにField Maskを「1」に変更する。
ノイズノードのCategory Maskと、物理ボディのField Maskのビットマスクを同じにしたので、ホタルはノイズノードの力を受けるようになる。
⇒「ビットマスクとは」
TestScene.swiftのtouchesBeganメソッドを以下のコードに変更する。
1 2 3 4 5 6 7 8 9 10 |
//画面タッチ開始時の呼び出しメソッド override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { //ノイズノードを取得する。 let noiseNode = self.childNodeWithName("noise") as? SKFieldNode //ノイズノードの効果を有効にする。 noiseNode?.enabled = true } |
以下は実際のプレイ動画。ホタルが。。揺れた。
ソースコードで実装する
シーンエディタではなく、ソースコードでノイズノードを実装する場合は以下のコードのようにする。ついでにホタルとライトを入切してホタルっぽさを演出してみた。
試してみる場合は、先ほどシーンエディタで追加したノイズノードを削除してから行うこと。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
//現在シーン設定時の呼び出しメソッド override func didMoveToView(view: SKView) { //シーンを画面サイズに合わせる。 self.scaleMode = .AspectFit //ノイズノードを作成する。 let noiseNode = SKFieldNode.noiseFieldWithSmoothness(0.5, animationSpeed: 0.0) //ノイズノードの名前を設定する。 noiseNode.name = "noise" //ノイズノードの効果を無効にする。 noiseNode.enabled = false //ノイズノードのカテゴリマスクを設定する。 noiseNode.categoryBitMask = 0b0001 //シーンの子にノイズノードを追加する。 self.addChild(noiseNode) //すべてのホタルをフェードイン、アウトさせる。 self.enumerateChildNodesWithName("hotaru[0-9]") { node, stop in //待機のアクションを作成する。 let waitAction = SKAction.waitForDuration(Double(arc4random_uniform(4)) + 1) //フェードアウトのアクションを作成する。 let outAction = SKAction.fadeAlphaTo(0.01, duration: Double(arc4random_uniform(4)) + 1) //フェードインのアクションを作成する。 let inAction = SKAction.fadeAlphaTo(1.0, duration: 0.0) //ライトの明るさを切り替えるアクションを作成する。 let runAction1 = SKAction.runBlock{ let lightNode = node.childNodeWithName("light") as? SKLightNode if lightNode!.falloff == 1.5 { lightNode!.falloff = 4.0 } else { lightNode!.falloff = 1.5 } } //アクションを実行順に並べる。 let allAction = SKAction.sequence([waitAction, outAction, runAction1, waitAction, inAction,runAction1]) //アクションを無限ループにする。 let actionLoop = SKAction.repeatActionForever(allAction) //アクションを実行する。 node.runAction(actionLoop) } } |
以下は実際のプレイ動画
設定項目
ノイズノードのアトリビュートインスペクタの設定項目は、概ね「Liner Gravity Field(以下、線形重力ノード)」と同じなので、そちらを参照されたし。
線形重力ノードの説明と異なる項目を説明する。
Strength
設定値を大きくすると、物理ボディの揺れ方が大きくなる。マイナスにすると訳が分からない動きになる。
以下の動画は、strengthを「5」に変更して実行した結果。
公式リファレンスには以下のように記載されている。加速はstrengthの大きさに比例する。計算される力は物理ボディの質量に比例する。といったことが書かれている。
⇒公式リファレンス「SKFieldNode」
The acceleration is proportional to the field strength in a pseudo-random direction. The calculated force is proportional to the physics body’s mass
以下の動画は、strengthは「5」のままで、ホタルノードのmass(質量)を「0.08 ⇒ 20.0」に変更して実行した結果。動きが遅くなった。
Anim. Speed
ノイズの発生割合。詳しくは次の記事を参照されたし。⇒「Anim. Speedとは」
以下の動画は、strength「5」、Anim. Speed「0.5」、ホタルノードのmass「0.08」の実行結果。実行する度に動きが変わり、いずれ画面の外に飛び出していく。
smoothness
動きの滑らかさ。詳しくは次の記事を参照されたし。⇒「smoothnessとは」