tmlib.jsでシーン制御してみる

前回までで
[お遊びゲーム開発その２](http://qiita.com/teradonburi/items/00f4b0bfb8ac8a80498d)
で述べた
下のやりたいことのうち①〜④を
その３〜その８でtmlib.jsで一通りできるようになったので
ゲームを量産できるように早速テンプレ化したいと思います。

①シーン制御
②画像アニメーション描画機能（2Dスプライト）
③音ファイル再生
④入力制御
⑤ゲームデータ、保存、読み込み

⑤はまぁゲームによって構造が違うと思うので、
別途自作するかライブラリを使うとしましょう

そんなわけで、使い回しできそうなテンプレ作ってみました
tmlib.jsでは
ローディング画面、タイトル画面、リザルト画面のクラスを
予め用意してくれているのでとっても楽です。

ローディング画面→タイトル画面→ゲーム画面→リザルト画面
の一連の流れをテンプレ化します

今回の全ソースコードです。
今回はHTMLもちゃんとかきます。
音ファイルを読み込まなければローカルでも動きます。
実際に作るときはアセット読み込み部分と
ゲームシーンクラス(GameScene)部分を修正します

```js:template.html
<!DOCTYPE html>

<html>
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, user-scalable=no" />
        <meta name="apple-mobile-web-app-capable" content="yes" />
        <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
        <title>ゲームタイトル</title>

        <script src="tmlib.js"></script>
<script>

/**
 * スクリーンサイズ
 */
var SCREEN_WIDTH  = 960;
var SCREEN_HEIGHT = 640;

/**
 * ゲーム起動処理
 */
tm.main(function() {
    // アプリケーション作成
    var app = tm.app.CanvasApp("#world");
    app.resize(SCREEN_WIDTH, SCREEN_HEIGHT); // 画面サイズに合わせる
    app.fitWindow(); // リサイズ対応
    app.background = "rgb(0, 0, 0)"; // 背景色をセット

    var loadingScene = tm.app.LoadingScene({
        assets: {"title":"title.jpg","result":"result.jpg"}, // 必要なアセットはここに追加
        nextScene: TitleScene,
        width: SCREEN_WIDTH,
        height: SCREEN_HEIGHT,
    });

    // シーンの切り替え
    app.replaceScene(loadingScene);

    // tmlibの実行
    app.run();
});


/**
 * TitleScene
 */
tm.define("TitleScene", {
    superClass : "tm.app.TitleScene",

    init : function() {
        this.superInit({
            title :  "ゲームタイトル",
            backgroundImage: "title",
            width :  SCREEN_WIDTH,
            height : SCREEN_HEIGHT
        });

        // 画面(シーンの描画箇所)をタッチした時の動作
        this.addEventListener("pointingend", function(e) {
            // シーンの遷移
            e.app.replaceScene(GameScene());
        });
    },
});


/**
 * GameScene
 */
tm.define("GameScene", {
    superClass : "tm.app.Scene",

    init : function() {
        this.superInit();

        this.score = 0;
    },

    update: function (app) {
        
        app.replaceScene(ResultScene(this.score));
    },
});


/**
 * ResultScene
 */
tm.define("ResultScene", {
    superClass : "tm.app.ResultScene",

    init : function(score) {

        // スコア
        this.superInit( {
            backgroundImage: "result",
            score: score,
            msg:      "ゲームタイトル",
            url:      "",
            hashtags: ["tmlib.js"],
            width:    SCREEN_WIDTH,
            height:   SCREEN_HEIGHT
        });
    },

    // Backボタンを押したらTitleSceneに戻る
    onnextscene: function (e) {
        e.target.app.replaceScene(TitleScene());
    },
});
           
</script>
    </head>
    <body>
        <canvas id="world"></canvas>
    </body>
</html>
```

タイトルとリザルト画面の画像はゲームあわせて差し替えます
今回は適当にフリーの画像を取ってきました

タイトル画面の画像（title.jpg）

![title.jpg](https://qiita-image-store.s3.amazonaws.com/0/55077/db054206-dab2-04a4-f5fd-4b2e6e031a56.jpeg)

リザルト画面の画像（result.jpg）

![result.jpg](https://qiita-image-store.s3.amazonaws.com/0/55077/43534dd7-9870-ee1f-4800-aeb8da0d8363.jpeg)

ざっくり解説します。

ページ表示時に
tm.app.LoadingSceneクラスで
必要なリソースを読み込みます

```
   var loadingScene = tm.app.LoadingScene({
        assets: {"title":"title.jpg","result":"result.jpg"}, // 必要なアセットはここに追加
        nextScene: TitleScene,
        width: SCREEN_WIDTH,
        height: SCREEN_HEIGHT,
    });

    // シーンの切り替え
    app.replaceScene(loadingScene);
```

アセットを読み込んでいる間、ひよこがくるくる回ります
かわいいですね

![loading.png](https://qiita-image-store.s3.amazonaws.com/0/55077/c8317c78-626c-4db0-d380-0f8803f39470.png)

この画面表示はtmlib.js内部で描画されているものなので
ローディング表示を変えたい場合は
・tm.app.LoadingSceneクラスを拡張するか
・ローディング処理はtm.asset.Loadingクラスを使って表示部分は独自実装する
必要があります。

タイトル画面はtm.app.TitleSceneクラスを使うと楽できます
初期化superInit関数にタイトル画面のラベル、背景を指定するだけで
タイトル画面ができます。

```
        this.superInit({
            title :  "ゲームタイトル",
            backgroundImage: "title",
            width :  SCREEN_WIDTH,
            height : SCREEN_HEIGHT
        });
```

リザルト画面はtm.app.ResultSceneクラスを使うと楽できます
初期化superInit関数に背景とメッセージ指定をすると
リザルト画面ができます。
しかも、twitter投稿もついているため、
スコアを投稿したり、urlリンク他の人にも遊んでもらったりもできます。
（この機能は非常に便利です）

```
        // スコア
        this.superInit( {
            backgroundImage: "result",
            score: score,
            msg:      "ゲームタイトル",
            url:      "",
            hashtags: ["tmlib.js"],
            width:    SCREEN_WIDTH,
            height:   SCREEN_HEIGHT
        });
```

リザルト画面はこんな感じです。

![スクリーンショット 2014-09-29 1.38.00.png](https://qiita-image-store.s3.amazonaws.com/0/55077/71d0d772-5575-3aa7-e35a-0ef7982caae0.png)

tweetボタンでtwitter投稿画面に遷移します

![スクリーンショット 2014-09-29 1.38.25.png](https://qiita-image-store.s3.amazonaws.com/0/55077/feaea9ac-4d6c-cab3-f373-f1d485866bde.png)

tmlib.jsをいじってみて
こうゆう細かいところに気が利いているのが嬉しいです。
ミニゲームくらいならこのテンプレでサクッと作れそうです。

次回は2D物理エンジン(box2dweb)やります