SONICMOOV LAB

この投稿はソニックムーブ Advent Calendar 201320日目の投稿になります。

どうも、ジョニーです。 過去にソニックのブログでTypeScriptの記事がありましたが、個人的にはCoffeeScriptの方が単純にコード量を少なくして書けるのと、インデント記法が好きなので勉強も兼ねてCoffeeScriptでHerlockを触ってみました。ついでに簡易的ではありますがシーン(ページ)遷移の管理クラスも作ってみたのでHerlockで何かアプリを作ってみようかなと思っている方の参考になれば幸いです。なお、Mac OSX 10.8環境で作業を行ったので適宜ご自身の環境に置き換えて読み進めて頂けたらと思います。

参考サイト

目次

  1. Node.js, Gruntをインストール
  2. Gruntfile.coffeeの設定
  3. コード説明
  4. CoffeeScriptを使ってみた感想

Node.js, Gruntをインストール

Macにnvm + Node.jsをインストールするGruntでCoffeeScriptを自動コンパイルするコピペを参考にNode.js, Gruntをインストールしてください。

Gruntfile.coffeeの設定

こちらもGruntでCoffeeScriptを自動コンパイルするコピペを参考に後のコード説明のところで紹介するGruntfile.coffeeの通りにファイルを設定してディレクトリ構造も同じようにしていただけたらあとは「grunt」コマンドを叩いてください。この状態で特定のディレクトリ内でCoffeeScriptファイルを作成すると自動的にJavascriptファイルも作成されるようになります。

コード説明

実行動画

プロジェクトはこちらに公開しているので手元にダウンロードするなりして参考にしながら読み進めて頂けたらと思います。

このプロジェクトを実行すると以下のようなフェードインフェードアウトを伴うシーン遷移アプリが実行されます。

Gruntfile.coffee

ここで行っているのはcoffeeディレクトリ内にcoffee拡張子のファイルが作成されたらappディレクトリ内に同じ構造でファイル(ディレクトリ)が作成されるように設定しています。

main.coffee

このアプリが起動するときに一番最初に読み込むファイルはmain.jsとなります。
main.jsを自動コンパイルしてファイル作成するために main.coffeeを作ります。
ここでは以下の流れでプログラムが走っています。

  • このアプリの独自のグローバルオブジェクト(@_app)を作成。(@_appにグローバルからアクセス出来る物を詰め込む)
  • 各シーンのコンテナーとなるステージを作成して@_appに詰め込んでどこからでもシーンをステージに追加出来るようにする。
  • レイヤーを作成してwindowに追加して、作成したレイヤーに先ほど作ったステージを追加する。
  • requirejsを読み込む(依存関係を管理するライブラリ)
  • 一番最初に表示するシーン(MainScene)とシーン遷移の管理クラスであるAppManagerを読み込む。(AppManagerはシングルトン)
  • 初期画面表示用のメソッドであるAppScene#runWithSceneの引数にMainSceneのインスタンス渡してMainSceneを画面に表示する

requirejsの使い方の説明はここでは省略いたします。
本家サイトを参考にしていただけたらと思います。

AppManager.coffee

AppManagerはこのプロジェクトのシーン遷移周りの管理を司るクラスです。
シングルトンにして使う理由は現在表示しているシーンの管理や、今回は未実装ですが
シーン遷移のスタックを保持したいなどの要望をこのクラスでまとめるためです。
AppManager#runWithSceneは初回起動時に一度だけ呼ぶメソッドで、
既にシーンを保持しているときなど初回起動以外で呼ぶと例外を投げるようにしています。
実際にシーンからシーンに遷移したいときはAppManager#replaceSceneに
遷移したいシーンのインスタンスを引数に渡す事でシーン遷移する事が出来ます。

MainScene.coffee

このファイルはBaseScene、GameScene、AppManagerに依存します。それぞれ依存するクラスの用途は以下の通りです。

  • BaseScene : シーンを作成するときに必ずBaseSceneを継承する
  • GameScene : 画面左上のボタン(色が違うところ)をタップしたときに遷移するシーン
  • AppManager : シーン遷移の管理クラス

AppManagerに関しては先ほども説明した通りシーン遷移のときに必ず使うクラスです。
今回は起動直後ではなくシーンからシーンへの遷移なのでAppManager#replaceSceneを使用しています。
GameSceneはMainSceneをほぼコピペしただけで、
シーンの背景色を変えたりrequirejsの循環参照を解決するためにrequireの呼び出し方を
イレギュラーな感じで使っているだけなのでここでは説明を省略します。
requirejsの循環参照の解決方法に関してはGameScene.coffeeの先頭に参考先を
コメントアウトして書いてあるのでそちらを参考にしていただけたらと思います。
BaseSceneは実際にシーンを画面に表示するときに色々とゴニョゴニョしてViewを画面に表示するように
@_app.stageにシーンを追加しています。
シーン遷移するときにただ単純に画面を切り替えるだけだと味気ないので
フェードイン/フェードアウトしてシーンを切り替えるようにしています。

BaseScene.coffee

先ほどの紹介したMainSceneでも見かけたメソッドがここでも出てきていますが、
それぞれのメソッドはシーン遷移時のライフサイクル用のメソッドとなります。

  • onPrepare : 画面を表示する前にあらかじめ読み込みたいリソースを読むフェーズ(今回は未実装)
  • onEnter : onPrepareが終わったら呼ばれるフェーズ。ビューの表示の追加を行ったりすることを想定
  • onShow : onEnterが終わったら呼ばれるフェーズ。ここではフェードインアニメーションが開始する。
  • onHide : シーンが切り替わるのではなく一時的に非表示にしたいときを想定。今回は未実装
  • onLeave : AppManager#replaceSceneが呼ばれたときに呼び出される。フェードアウトアニメーションが開始する。
  • onDestroy : シーンを破棄するフェーズ。 onLeaveで呼び出したフェードアウトアニメーションが終了したら呼び出されてビューを破棄する

ライフサイクルとは別にサブクラスでも使われているメソッドにupdateが用意されています。
毎フレーム何か処理したい(アニメーションなど)がある場合はサブクラスのupdateメソッドをオーバーライドして
使うことを想定して作りました。
フェードイン/フェードアウトアニメーションを行っているメソッドであるfadein/fadeoutメソッドは
単純に15フレームで少しずつアルファの値を変えることで表現しています。

CoffeeScriptを使ってみた感想

CoffeeScriptは普段あまり使わないので実際にHerlockでCoffeeScriptを使うのは
最初は苦労するかなと思っていましたが、結構すんなり書けて良いなと思いました。
普段クラスの概念があるプログラミング言語でプログラムしている人にとってクラスが使えるのは
重要な点かと思います。
typescriptと違って型の定義とかは出来ませんが、少ない記述でインデントで記述出来る事によって
プログラムがすっきりする点だけでもCoffeeScriptを使ってみる価値は大いにあるのではないでしょうか。

実際に業務でも小規模な案件の時は積極的に使ってみようかな・・・

あわせて読みたい記事