GPS瞬間移動クマについて、実装内容とか工夫点とか

出しといてすっかり忘れていたので、

GPS(位置情報)を利用するゲームGPS瞬間移動クマを9leapに投稿しました。

リポジトリ:https://bitbucket.org/nanmo/gpskuma

f:id:nanmo:20110522130913p:image:w640


修行(?)の結果瞬間移動を身につけたクマの実力を測るゲームです。

ゲームとしては2度タッチする必要があり、

  • 初回タッチ-> 瞑想開始、GPS起点位置決定、トラッキング開始
  • 2回目のタッチ-> トラッキング終了、GPS終点位置決定、基点位置との直線距離計算・表示

ユーザー操作としてはこれだけです。

2回目タッチしたあとの瞬間移動時にランダムにクマに何か起こるようにしていますが、まあそこは完全にお遊び(=GPS移動距離は関係ない)で概ね以下のような種類と確率になっています。

  • 何も起こらない(30%)
  • 目が細くなる(25%)
  • 白クマに変化(10%)
  • 雌クマに変化(10%)
  • スケボーに乗る(10%)
  • 人間(男)に変化(5%)
  • 人間(女)に変化(5%)
  • 爆発して消滅(5%)

全種類はそこそこ繰り返せば見ることができるはずです。

以下なんとなく工夫して実装した点

初回タッチとその後のトラッキングで呼ぶメソッドが違う

  • 初回タッチ時 navigator.geolocation.getCurrentPosition
  • その後のトラッキング navigator.geolocation.watchPosition

当初はすべて navigator.geolocation.getCurrentPosition で位置情報を取得する実装にしていたのですが、iOSのSafariだとgetCurrentPositionのあとに短時間のトラッキングが行われる仕様で、実質的に正確な現在位置情報は取得できないことがわかりました。
なので、初回タッチ後Safariでトラッキングが行われ続けるのはwatchPositionの仕様です

初回タッチ時に navigator.geolocation.getCurrentPosition のママなのは、初回時にはむしろその正確でないトラッキングの方が都合が良かったのでそのまま残しました。*1

瞬間移動実行時の音声再生

よく振ってからお開けください 好きなだけ良く振ってからお開けください
でも音がなるような実装にはしていたのですが、どうしても越えられない仕様がありました。

それは、

  • iOSのSafariにおいてAudioのplay()はユーザーによるインタラクション内(click,touch等)でしか実行できない。
  • iOSのSafariにおいてAudioのload()では音声の事前読み込みは行われず、play()実行時に読み込み->再生という動きになる
  • つまり"タッチしてすぐ音が出るSE"のような実装はどうしても(特に初回)音が遅れる

という点です。

これをGPS瞬間移動クマでは以下のように解決しています。

  • 初回タッチ時に 瞬間移動時の音(bear_transport_se.mp3)をplay()、即pause()
  • 2回目タッチ時に、pause()していた音をplay()

こうすることで、ほぼ遅れることなく瞬間移動時のSEを鳴らすことができるようになりました。
ただこれは、GPS瞬間移動クマが位置情報ゲームであり、初回タッチ時から2回目タッチまでにある程度時間が空くことを利用した実装です。あとたまにうまくいかない場合もあります。(長時間放っておくと再読込が必要になったりする)

あと同時に微妙な工夫として

  • 瞬間移動のアニメーションシーケンスの長さは固定
  • 音はそれに合わせた無音を含んだ状態の物

ということもしています。

なんとなく結論

  • 現状のHTML5でAudioとかGPSとか加速度センサーいじるといろいろめんどうっていうかデバイス間/ブラウザ間での相互互換性が非常にアレなので、まだFlashなくていいよとかいう状況でもないよね
  • 最終的にWebがHTML5で席巻されてもFlashはミドルウェアとして生き続けるような気がする(CS5.5でiOS,Android向けにアプリ出力が可能に)

*1:GPSが使えるかどうかのチェックもそこでできるというのもありますが