はじめに
SpriteKit でノードに動きを付けたい場合は SKAction を使います。
今回は SKAction についてのまとめです。
準備
今回紹介するコードは全て以下の構成になっています。
1 2 3 4 5 6 7 8 9 10 11 12 |
final class HogeScene: SKScene { private let frog = SKSpriteNode(imageNamed: "frog_blue") override func didMove(to view: SKView) { frog.position = .init(x: frame.midX, y: frame.midY) addChild(frog) } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { // ここでアクション処理 } } |
縦横移動
縦横移動。
1 2 3 4 5 6 7 8 9 10 |
// 右に10pt移動 frog.run(.moveBy(x: 10, y: 0, duration: 0.3)) // 左に10pt移動 frog.run(.moveBy(x: -10, y: 0, duration: 0.3)) // 上に10pt移動 frog.run(.moveBy(x: 0, y: 10, duration: 0.3)) // 下に10pt移動 frog.run(.moveBy(x: 0, y: -10, duration: 0.3)) // 右に10pt上に10pt移動 frog.run(.moveBy(x: 10, y: 10, duration: 0.3)) |
他にも下記があるようです。
1 2 3 4 |
class func move(by: CGVector, duration: TimeInterval) -> SKAction class func move(to: CGPoint, duration: TimeInterval) -> SKAction class func moveTo(x: CGFloat, duration: TimeInterval) -> SKAction class func moveTo(y: CGFloat, duration: TimeInterval) -> SKAction |
パスで移動
パスのとおりに動かす方法です。
1 2 3 4 |
let path = UIBezierPath() path.move(to: .zero) path.addCurve(to: CGPoint(x: 100, y: 0), controlPoint1: CGPoint(x: 20, y: 20), controlPoint2: CGPoint(x: 50, y: 50)) frog.run(.follow(path.cgPath, duration: 1.5)) |
他にも下記があるようです。
1 2 3 |
class func follow(CGPath, speed: CGFloat) -> SKAction class func follow(CGPath, asOffset: Bool, orientToPath: Bool, duration: TimeInterval) -> SKAction class func follow(CGPath, asOffset: Bool, orientToPath: Bool, speed: CGFloat) -> SKAction |
回転
回転。
1 2 3 4 |
// 反時計回りに90°回転 frog.run(.rotate(byAngle: .pi/2, duration: 0.3)) // 時計回りに90°回転 frog.run(.rotate(byAngle: -.pi/2, duration: 0.3)) |
他にも下記があるようです。
1 2 |
class func rotate(toAngle: CGFloat, duration: TimeInterval) -> SKAction class func rotate(toAngle: CGFloat, duration: TimeInterval, shortestUnitArc: Bool) -> SKAction |
アニメーション速度変更
下記のようにすると回転アニメーションがだんだん速くなる(たぶん他のアクションと組み合わせて使うやつ?)。
1 2 3 4 |
frog.run(.group([ .speed(by: 100, duration: 10), .repeatForever(.rotate(byAngle: .pi, duration: 3)) ])) |
他にも下記があるようです。
1 |
class func speed(to: CGFloat, duration: TimeInterval) -> SKAction |
拡大・縮小
拡大・縮小。
1 2 3 4 |
// 1.5倍に拡大 frog.run(.scale(by: 1.5, duration: 0.3)) // 1/2に縮小 frog.run(.scale(by: 0.5, duration: 0.3)) |
他にも下記があるようです。
1 2 3 4 5 6 |
class func scale(to: CGSize, duration: TimeInterval) -> SKAction class func scale(to: CGFloat, duration: TimeInterval) -> SKAction class func scaleX(by: CGFloat, y: CGFloat, duration: TimeInterval) -> SKAction class func scaleX(to: CGFloat, y: CGFloat, duration: TimeInterval) -> SKAction class func scaleX(to: CGFloat, duration: TimeInterval) -> SKAction class func scaleY(to: CGFloat, duration: TimeInterval) -> SKAction |
フェードイン・フェードアウト
フェードイン・フェードアウト。
1 2 3 4 |
// フェードイン(事前にfrog.alpha = 0にしておく) frog.run(.fadeIn(withDuration: 0.5)) // フェードアウト frog.run(.fadeOut(withDuration: 0.5)) |
他にも下記があるようです。
1 2 |
class func fadeAlpha(by: CGFloat, duration: TimeInterval) -> SKAction class func fadeAlpha(to: CGFloat, duration: TimeInterval) -> SKAction |
リサイズ
1 2 |
// 幅+10、高さ+10 frog.run(.resize(byWidth: 10, height: 10, duration: 0.5)) |
他にも下記があるようです。
1 2 3 |
class func resize(toHeight: CGFloat, duration: TimeInterval) -> SKAction class func resize(toWidth: CGFloat, duration: TimeInterval) -> SKAction class func resize(toWidth: CGFloat, height: CGFloat, duration: TimeInterval) -> SKAction |
テクスチャ変更
テクスチャ変更。
1 |
frog.run(.setTexture(.init(imageNamed: "frog_green"))) |
他にも下記があるようです。
1 2 3 4 5 6 7 |
class func setTexture(SKTexture, resize: Bool) -> SKAction class func animate(with: [SKTexture], timePerFrame: TimeInterval) -> SKAction class func animate(with: [SKTexture], timePerFrame: TimeInterval, resize: Bool, restore: Bool) -> SKAction class func setNormalTexture(SKTexture) -> SKAction class func setNormalTexture(SKTexture, resize: Bool) -> SKAction class func animate(withNormalTextures: [SKTexture], timePerFrame: TimeInterval) -> SKAction class func animate(withNormalTextures: [SKTexture], timePerFrame: TimeInterval, resize: Bool, restore: Bool) -> SKAction |
配列で渡せばこの記事みたいにパラパラ漫画もできます。
SpriteKitでパラパラ漫画(Swift)
色変更
色変更。
1 2 |
// colorBlendFactorは0~1で0だと色は変化しない frog.run(.colorize(with: .systemPink, colorBlendFactor: 1, duration: 0.5)) |
他にも下記があるようです。
1 |
class func colorize(withColorBlendFactor: CGFloat, duration: TimeInterval) -> SKAction |
音声
音声再生とかもある模様。
1 2 |
// sound.mp3ファイルを再生 frog.run(.playSoundFileNamed("sound", waitForCompletion: false)) |
他にも下記があるようです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class func play() -> SKAction class func pause() -> SKAction class func stop() -> SKAction class func changePlaybackRate(to: Float, duration: TimeInterval) -> SKAction class func changePlaybackRate(by: Float, duration: TimeInterval) -> SKAction class func changeVolume(to: Float, duration: TimeInterval) -> SKAction class func changeVolume(by: Float, duration: TimeInterval) -> SKAction class func changeObstruction(to: Float, duration: TimeInterval) -> SKAction class func changeObstruction(by: Float, duration: TimeInterval) -> SKAction class func changeOcclusion(to: Float, duration: TimeInterval) -> SKAction class func changeOcclusion(by: Float, duration: TimeInterval) -> SKAction class func changeReverb(to: Float, duration: TimeInterval) -> SKAction class func changeReverb(by: Float, duration: TimeInterval) -> SKAction class func stereoPan(to: Float, duration: TimeInterval) -> SKAction class func stereoPan(by: Float, duration: TimeInterval) -> SKAction |
ノード削除
ノード削除のアクション。
1 |
frog.run(.removeFromParent()) |
アクションの組み合わせ
同時実行
1 2 3 4 5 6 |
// 180度回転、1.5倍拡大、右に10上に10移動を同時に実行 frog.run(.group([ .rotate(byAngle: .pi, duration: 0.5), .scale(by: 1.5, duration: 0.5), .moveBy(x: 10, y: 10, duration: 0.5) ])) |
順次実行
1 2 3 4 5 6 |
// 180度回転、1.5倍拡大、右に10上に10移動を順番に実行 frog.run(.sequence([ .rotate(byAngle: .pi, duration: 0.5), .scale(by: 1.5, duration: 0.5), .moveBy(x: 10, y: 10, duration: 0.5) ])) |
繰り返し実行
1 2 3 4 |
// 180度回転を3回繰り返し frog.run(.repeat(.rotate(byAngle: .pi, duration: 0.5), count: 3)) // 180度回転を無限ループ frog.run(.repeatForever(.rotate(byAngle: .pi, duration: 0.5))) |
遅延実行
1秒待ってから実行などの遅延処理。
1 2 3 4 5 |
// 1秒後に右に10移動 frog.run(.sequence([ .wait(forDuration: 1), .moveBy(x: 10, y: 0, duration: 0.5) ])) |
他にも下記があるようです。
1 |
class func wait(forDuration: TimeInterval, withRange: TimeInterval) -> SKAction |
逆再生
reversed
を使うとアクションの逆再生ができます。
1 2 3 4 5 6 |
// 右に10移動したあと左に10移動する let action = SKAction.moveBy(x: 10, y: 0, duration: 0.5) frog.run(.sequence([ action, action.reversed() ])) |
表示・非表示
表示・非表示。
1 2 3 4 |
// 表示 frog.run(.unhide()) // 非表示 frog.run(.hide()) |
PhysicsBody関連
PhysicsBody 関連のやつですが今回は割愛。
下記があるようです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class func applyForce(CGVector, duration: TimeInterval) -> SKAction class func applyTorque(CGFloat, duration: TimeInterval) -> SKAction class func applyForce(CGVector, at: CGPoint, duration: TimeInterval) -> SKAction class func applyImpulse(CGVector, duration: TimeInterval) -> SKAction class func applyAngularImpulse(CGFloat, duration: TimeInterval) -> SKAction class func applyImpulse(CGVector, at: CGPoint, duration: TimeInterval) -> SKAction class func changeCharge(to: Float, duration: TimeInterval) -> SKAction class func changeCharge(by: Float, duration: TimeInterval) -> SKAction class func changeMass(to: Float, duration: TimeInterval) -> SKAction class func changeMass(by: Float, duration: TimeInterval) -> SKAction class func strength(to: Float, duration: TimeInterval) -> SKAction class func strength(by: Float, duration: TimeInterval) -> SKAction class func falloff(to: Float, duration: TimeInterval) -> SKAction class func falloff(by: Float, duration: TimeInterval) -> SKAction |
インバースキネマティクス
インバースキネマティクス?もあるらしい。初級では使わなそうなので割愛。
こんなのがあるらしい。
1 2 3 4 |
class func reach(to: CGPoint, rootNode: SKNode, duration: TimeInterval) -> SKAction class func reach(to: CGPoint, rootNode: SKNode, velocity: CGFloat) -> SKAction class func reach(to: SKNode, rootNode: SKNode, duration: TimeInterval) -> SKAction class func reach(to: SKNode, rootNode: SKNode, velocity: CGFloat) -> SKAction |
参考
Working with Inverse Kinematics
おわりに
これで SpriteKit で色々表示できるようになりました!もうなんか作れそうな気がしてきます!
コメント