SpriteKit で SpriteNode などにアニメーション等の動作をさせたりするときに SKAction を使います。
この SKAction、複数の SKAction を組み合わせることができます。
直列に実行
1つの SKAction が終わったらすぐ次の SKAction を実行したいとき
SKAction.sequence([someAction1, someAction2])
並列に実行
2つの SKAction を同時に実行したいとき
SKAction.group([someAction3, someAction4])
直列/並列に実行
では、2つの SKAction.gruop を直列で実行したいときは?
let group1 = SKAction.group([someAction1, someAction2]) let group2 = SKAction.group([someAction3, someAction4]) let sequence = SKAction.sequence([gruop1, group2]) self.run(sequence)
とかやればいいわけです。
以下にも書かれています。
SpriteKitでのアニメーションまとめ – 2016年02月05日
https://qiita.com/sa-k0/items/c5be9e0912c11631bae1
期待通り動作しない場合
上記でうまくいかない場合もあります。
原因としては、someAction の中に SKAction.repeatForever が入っている場合等。
例えば、あるキャラクターが足踏みしているアニメーションを repeatForever で設定することが多いと思います。
この状態で、例えば、「左に3歩進んだ後に、上に5歩進む」といったアニメーションをしたい場合、
repeatForever を含む Action を切り替えたいのですが、 repeatForever が永久に終わらないため、次に進みません。
このような場合でも解決策があります。
SKAction の run メソッドには completion があるので、ここでアニメーションを切り替えて、また動く action を run すればいいのです。
run(_:completion:)
https://developer.apple.com/documentation/spritekit/sknode/1483103-run
雰囲気をつかんでいただきたいのですが、下記のように書けば動作します。
node.run(actionAnimationLeft) node.run(actionsMoveLeft, completion: { node.run(actionAnimationRight) node.run(actionMoveRight, completion: { node.run(actionAnimationUp) node.run(actionMoveUp) }) })
ドラクエ3のオープニングで、お母さんが勇者を自動でお城に連れてってくれるシーンがありますが、そこで上記のコードが使われています。
dq3_ios – github
https://nomad.office-aship.info/dq3-ios
難点としては、このように書くと、どんどんネストが深くなっていくことでしょうか。
しかし、Xcode 13 で swift 5.5 による async/wait が導入されると、このようなネスト地獄が解消されると思います。
解消されたら、そちらのコードも載せていきたいと思います。
Swift 6 & 5.5 まとめ
https://nomad.office-aship.info/swift-6
Swift 関連書籍
SwiftUI開発レシピ iOS 14 対応
SwiftUI iPhoneアプリ開発入門ノート[2020] iOS 14 対応
SwiftUI 徹底入門
SwiftUIではじめるiPhoneアプリプログラミング入門
iOS/macOS UIフレームワーク SwiftUIプログラミング
コメント