こんにちは、のっくんです。
今日はSpriteKitを使ってキャラクターをジャンプさせる方法をご紹介します。

実装してみた内容としては以下の通り。
- ジャンプのアニメーションを作る
- ジャンプボタンでジャンプする
順番に見ていきます。
ジャンプのアニメーションを作る
7枚の画像をパラパラ漫画のように表示させてアニメーションを作ります。
1枚あたりの表示時間は0.08秒にしました。
表示時間はコードを動かしつつ調整するのが良いです。
func createAnimations() { // ジャンプのアニメーションを追加するよ let jumpFrames:[SKTexture] = [textureAtlas.textureNamed("2_entity_000_JUMP_000"), textureAtlas.textureNamed("2_entity_000_JUMP_001"), textureAtlas.textureNamed("2_entity_000_JUMP_002"), textureAtlas.textureNamed("2_entity_000_JUMP_003"), textureAtlas.textureNamed("2_entity_000_JUMP_004"), textureAtlas.textureNamed("2_entity_000_JUMP_005"), textureAtlas.textureNamed("2_entity_000_JUMP_006"), ] // 1フレームあたりの表示時間は0.05秒 jumpAnimation = SKAction.animate(with: jumpFrames,timePerFrame: 0.08) } func startJumpAnimation(){ self.run(jumpAnimation) }
アイドル状態やランニングと違って、一回限りのアクションになっています。
何回も実行する必要はありません。
ジャンプの制御
ジャンプボタンが押されたらジャンプのフラグをオンにします。
指がボタンから離れたらフラグをオフにします。
ボタンに名前をつけて、押されたボタンを判別するようにしています。
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { // タッチしたボタンによって処理を分ける for touch: AnyObject in touches { let location = touch.location(in: self) let node = self.atPoint(location) if ( node.name == "Jump") { self.nokkuman.jump = true } } } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { for touch: AnyObject in touches { let location = touch.location(in: self) let node = self.atPoint(location) if node.name == "Jump" { self.nokkuman.jump = false } } }
ジャンプの処理は、GameScene.swiftのupdateに記載します。
updateはフレームが更新されるたびに呼ばれます。
var updateTime:Double = 0 // ジャンプ時間のインターバルを設定する var jumpInterval:Double = 0.8 override func update(_ currentTime: TimeInterval) { // ジャンプフラグが立っていなければ終了 guard self.nokkuman.jump else { return } // インターバルを空けないと再度ジャンプできないようにする if updateTime == 0 || currentTime - updateTime > jumpInterval { startJump() updateTime = currentTime } }
ジャンプのフラグを確認してオンだったら、ジャンプ処理とアニメーションを開始します。
ジャンプ中に再度ジャンプボタンを押す行為を防ぐために、インターバル時間を設定しています。
連続してジャンプができてしまうと、鳥のように空を飛ぶことができてしまいます。
それはそれでゲームとしては面白いかもしれませんが、今回は人間キャラなので空を飛ぶのは禁止します。
updateTimeが0なのは初回時のジャンプ時です。
初回時は無条件でジャンプできるようにしています。
2回目以降は、現在時刻から前回のジャンプ時刻の差分を計算し、インターバル時間より大きいか比較しています。
ジャンプ処理
func startJump(){ self.nokkuman.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 15000)) self.nokkuman.startJumpAnimation() }
applyImpulseでy軸方向に衝撃を与えてキャラクターを浮かせます。
すいません、dyの値は割と適当です。
小さい値だとジャンプの高さが低かったので大きめにしました。
SKPhysicsBodyにはapplyImpulseとapplyForceがあります。
applyForceは連続的に加速度を与える時に使います。
上昇するロケットや鳥が羽ばたく時ですね。
今回は一瞬だけ衝撃を与えてジャンプさせるため、applyImpulseを使います。
アニメーションを開始するのもこのタイミングで行います。