【Swift】SpriteKitの使い方。竜巻に吹き飛ばされたかのように物理ボディを加速させる。(Swift 2.2、XCode 7.3)
Vortex Fieldとは
本記事では、SKFieldNodeの「Vortex Field(以下、旋風ノード)」について説明する。
旋風ノードとは、渦巻き方向に物理ボディを加速させるノードである。まるで竜巻に吹き飛ばされたかのように、物理ボディは旋風ノードの周りを回って離れていく。
旋風ノードを使ってみる
実際に旋風ノードをシーンに配置して物理ボディを回転させてみよう。以降の手順を行う前のXcodeプロジェクトをGitHubに置いたので、試してみる方はご利用下さい。⇒「テスト用プロジェクト」
事前準備ではボールと四角形をシーンに配置しておいた。
下図赤枠のSKSファイルを選択してシーンエディタを開く。黄緑枠のオブジェクトライブラリボタンを押して部品一覧を表示し、ドラッグ&ドロップで「Vortex Field」をシーンに配置する(紫矢印)。
黄枠のアトリビュートインスペクタボタンを押して設定画面を表示し、Nameに「vortex」、Parentに「center_point」、Category Maskに「1」、Enabledのチェックを外す。
黒いボールの画像を選択、下図赤枠のアトリビュートインスペクタボタンを押して設定画面を表示し、Field Maskに「1」を入力する。
旋風ノードのCategory Maskと、物理ボディのField Maskのビットマスクを同じにしたので、ボールは旋風ノードの物理的効果を受けるようになる。
⇒「ビットマスクとは」
TestScene.swiftのtouchesBeganメソッドを以下のコードに変更する。
1 2 3 4 5 6 7 8 9 10 11 |
//画面タッチ時の呼び出しメソッド override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { //旋風ノードを取得する。 let vortexNode = self.childNodeWithName("//vortex") as? SKFieldNode //旋風ノードの有効無効を切り替える。 vortexNode?.enabled = !vortexNode!.enabled } |
以下は実際のプレイ動画。ボールがすぐに外に飛び出していった。。
(・□・;)え!
旋風ノードと物理ボディを結んだ直線の垂直方向に力が働くので、ボールは旋風ノードの周りを回ることになるが、求心力が働いていないためボールは旋風ノードからすぐに遠ざかっていく。
では、以下のコードのように画面端に壁を作るとどうなるか。
1 2 3 4 5 6 7 8 9 10 11 |
//現在シーン設定時の呼び出しメソッド override func didMoveToView(view: SKView) { //シーンを画面サイズに合わせる。 self.scaleMode = .AspectFit //画面端に物理ボディを設定する。 self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame) } |
以下は実際のプレイ動画。壁にぶつかりながら、旋風ノードの周りを左回りにまわるようになった。
壁にゴツゴツ当たって動きが乱れているので、円形の壁を設置してみよう。
下図赤枠のSKSファイルを選択してシーンエディタを開く。黄緑枠のオブジェクトライブラリボタンを押して部品一覧を表示し、ドラッグ&ドロップで「Color Sprite」をシーンに配置する(紫矢印)。
黄枠のアトリビュートインスペクタボタンを押して設定画面を表示し、Textureに「kabe_circle1」、Body Typeに「Alpha mask」、DynamicとAffected By Gravityのチェックを外す。これで上半分の壁ができた。同じようにして、下半分の壁も配置する。
以下は実際のプレイ動画。壁に沿ってグルグル回るようになった。
ソースコードで実装する
シーンエディタではなく、ソースコードで旋風ノードを実装する場合は以下のコードのようにする。試してみる場合は、先ほどシーンエディタで追加した抗力ノードを削除してから行うこと。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
//現在シーン設定時の呼び出しメソッド override func didMoveToView(view: SKView) { ‥省略‥ //旋風ノードを作成する。 let vortexNode = SKFieldNode.vortexField() //旋風ノードの名前を設定する。 vortexNode.name = "vortex" //旋風ノードのカテゴリマスクを設定する。 vortexNode.categoryBitMask = 0b0001 //旋風ノードを無効にする。 vortexNode.enabled = false //中心ノードを取得する。 let centerNode = self.childNodeWithName("center_point") as? SKSpriteNode //中心ノードの子に旋風ノードを追加する。 centerNode?.addChild(vortexNode) } |
設定項目
旋風ノードのアトリビュートインスペクタの設定項目は、概ね「Liner Gravity Field(以下、線形重力ノード)」と同じなので、そちらを参照されたし。
線形重力ノードの説明と異なる項目を説明する。
Strength
物理ボディの加速度を指定する。プラス値を設定した場合は左回り、マイナス値を設定した場合は右回りに回転する。
以下の動画はStrengthに「-0.1」を設定した場合
壁を使わずにまわす
壁を使わずに旋風ノードの周りを回転させる方法について考察してみた。
人工衛生が地球の周りを回る原理と同じように、旋風ノードの方向に求心力を発生させれば、ボールが旋風ノードから離れづらくなると考えた。
そこで、以前記事で紹介した「Radial Gravity Field(放射重力ノード)」と旋風ノードを重ねて配置し、Strengthを調整しながらボールを回してみた。
以下が実際のプレイ動画。んーなかなか調整が難しい。