LoginSignup
2
1

More than 5 years have passed since last update.

自作アニメーションループを試す

Last updated at Posted at 2017-12-10

この記事はQuadアドベントカレンダー10日目の記事です。
前回からの続きです。
別スレッドでループを作ることができたので、ちょっと試してみたいと思います。動くも飲みながらでないとモチベーションも下がってしまうので...

シンプルエンジンクラスを作る

簡易なエンジンクラスを作ります。シングルトンかstaticクラスがやりやすいと思います。

class SimpleAnimationEngine {

    public static let shared: SimpleAnimationEngine = SimpleAnimationEngine()
    private var thread:Thread?
    private var isRunning:Bool   = true
    private var fps:TimeInterval = 0
    private var displayLink:CADisplayLink?
}

とりあえずこんな感じ。

必要なインターフェイスを定義を追加

まずは、実行と停止を用意します。

func start() -> Void {
    self.isRunning = true
    self.thread = Thread(target: self, selector: #selector(self.threadLoop(_:)), object: nil)
    self.thread?.start()
}

func stop() -> Void {
    self.isRunning   = false
    self.displayLink?.remove(from: RunLoop.current, forMode: .defaultRunLoopMode)
    self.displayLink = nil
}

ループ部分は前回と同じです。

@objc func threadLoop(_ sender:AnyObject) -> Void {
   self.displayLink = CADisplayLink(target: self, selector: #selector(self.engineLoop(_:)))
   self.displayLink?.preferredFramesPerSecond = Int(self.fps)
   self.displayLink?.add(to: RunLoop.current, forMode: .defaultRunLoopMode)
   while self.isRunning {
       RunLoop.current.run(until: Date(timeIntervalSinceNow: 1/fps))
   }
}

delegateを用意する

アニメーションは同時に複数実行することもあると思うので、delegate用に配列を用意します。

private var listeners:[EnableAnimation] = []

プロトコロルも定義します。

protocol EnableAnimation {
    func update() -> Void
    func draw() -> Void
}

登録メソッドを用意します。

func addAnimation(listener:EnableAnimation) -> Void {
    self.listeners.append(listener)
}

updateとdrawの追加

数値計算と描画のメソッドを追加します。登録されているオブジェクトのメソッドを順番に実行しています。

@objc func engineLoop(_ sender:AnyObject) -> Void {
   self.update()
   self.draw()
}

private func update() -> Void {
   self.listeners.forEach { (animation: EnableAnimation) in
       animation.update()
   }
}

private func draw() -> Void {
   self.listeners.forEach { (animation: EnableAnimation) in
       animation.draw()
   }
}

とりあえず準備はできました。あとは、EnableAnimationを実装した型を用意して試すだけです。

試してみる

Engineのインスタンスを取得

var engine:SimpleAnimationEngine = SimpleAnimationEngine.shared

FPSを設定し、実行。

self.engine.initalize(fps: 60)
self.engine.addAnimation("ここでEnableAnimation型のオブジェクトを渡します。")
self.engine.start()

サンプルも作りました。

簡単なサンプルを作ってみました。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1