Apple Engine

Apple, iPhone, iOS, その周辺のことについて

Apple Watch の デジタルクラウンで寿司を回す

今回は Touch Bar のやつよりも簡単なので、
寿司を回す職人の方は試してみてはいかがでしょうか。

私、Apple Watch 持っていない貧民ですので Sumilator 上でしか試していません。
実機で動かなかった場合はごめんなさい。

ちなみに Sumilator 上でデジタルクラウンを試す場合はマウスのホイールか、トラックパッドで二本指スワイプをしましょう。

 

1. Xcode 8.3.2 でプロジェクトを作る

Extension からやるとスクリーショット撮るのが面倒なので
Cross-Platform の SpriteKit でプロジェクトを作ります。

f:id:x67x6fx74x6f:20170522183713p:plain

 

今回は「SushiWatch」というプロジェクト名にしました。

f:id:x67x6fx74x6f:20170522183724p:plain

 

2. SpriteKit の watchOS 用の Scene を修正する

SpriteKit の Scene に関する動作は GameScene.swift にあります。
58 〜 64 行目にテンプレートで watchOS の記述がありますが必要ないので消します。

f:id:x67x6fx74x6f:20170522183850p:plain

 

代わりに以下の命令を書きます。

label?.text = "🍣"
label?.fontSize = 500

f:id:x67x6fx74x6f:20170522183905p:plain

 

ビルドする項目を iPhone と watchOS シミュレーターにしてビルド。

f:id:x67x6fx74x6f:20170522184016p:plain

 

美味しそうな寿司が表示されます。

f:id:x67x6fx74x6f:20170522183920p:plain

 

3. SpriteKit の Scene へ寿司を回すメソッドを追加する

以下の1秒で r 分回る命令を適当なところに入れます。

func rotateText(_ r:Float){
    self.label?.run(
        SKAction.rotate(byAngle: CGFloat(r), duration: 1)
    )
}

 

試しに初期化のところに回転の関数を入れてみましょう

label?.text = "🍣"
label?.fontSize = 500
self.rotateText(1)

 

寿司がラジアンの 1 の値で回ります。
回転が確認できたら self.rotateText(1) は消しても大丈夫です。

f:id:x67x6fx74x6f:20170522185410p:plain

 

4. Extension 側にメソッドを追加する
  • デジタルクラウンのデリゲートを設定
  • watchOS の Extension に Scene を呼び出し
  • デジタルクラウンの初期化と操作を呼び出し
  • デジタルクラウンのデリゲートの内容を設定

f:id:x67x6fx74x6f:20170522184534p:plain

 

InterfaceController.swift を開き、デジタルクラウン使用するためのデリゲートを追加。

class InterfaceController: WKInterfaceController, WKCrownDelegate {
    ...
}

 

使い回せるように変数として Scene 呼び出し

private var scene:GameScene!

 

override func awake() 内に初期化を focus で操作の呼び出し

let sequencer = self.crownSequencer
sequencer.delegate = self
sequencer.focus()

 

以下のデジタルクラウンのデリゲート内容を設定。内容は scene で設定したメソッドを呼び出しているだけの簡単なものです。
あとはビルドするだけです。

func crownDidRotate(_ crownSequencer: WKCrownSequencer?, rotationalDelta: Double) {
    scene.rotateText(Float(rotationalDelta))
    print("DigitalCrowm - Delta:\(rotationalDelta) PerSecond:\(self.crownSequencer.rotationsPerSecond)")
}

func crownDidBecomeIdle(_: WKCrownSequencer?) {
    print("デジタルクラウンが止まりました")
}

crownDidBecomeIdle は止まった時に呼ばれます。 必要なければ消してください

 

InterfaceController.swift の全コード

import WatchKit
import Foundation

class InterfaceController: WKInterfaceController, WKCrownDelegate {

    @IBOutlet var skInterface: WKInterfaceSKScene!
    
    private var scene:GameScene!
    
    override func awake(withContext context: Any?) {
        super.awake(withContext: context)
        
        scene = GameScene.newGameScene()
        
        // Present the scene
        self.skInterface.presentScene(scene)
        
        // Use a preferredFramesPerSecond that will maintain consistent frame rate
        self.skInterface.preferredFramesPerSecond = 30
        
        let sequencer = self.crownSequencer
        sequencer.delegate = self
        sequencer.focus()
    }
    
    override func willActivate() {
        // This method is called when watch view controller is about to be visible to user
        super.willActivate()
    }
    
    override func didDeactivate() {
        // This method is called when watch view controller is no longer visible
        super.didDeactivate()
    }

    // Digital Crown Delegate
    func crownDidRotate(_ crownSequencer: WKCrownSequencer?, rotationalDelta: Double) {
        scene.rotateText(Float(rotationalDelta))
        print("DigitalCrowm - Delta:\(rotationalDelta) PerSecond:\(self.crownSequencer.rotationsPerSecond)")
    }
    
    func crownDidBecomeIdle(_: WKCrownSequencer?) {
        print("デジタルクラウンが止まりました")
    }
}

 

まとめ

基本的にはデリゲートの設定だけで、
デジタルクラウンを回して反応するコードが簡単にかけます。

皆様もいろいろなものをデジタルクラウンで回してみてはいかがでしようか。