連載
» 2013年04月01日 18時00分 公開

enchant.jsで重要なスプライトとシーンを使うにはenchant.jsでHTML5+JavaScriptゲーム開発入門(3)(3/4 ページ)

[佐藤浩昭, 大関隆介,ゆめみ]

「シーン」を使いこなそう

 次に、ゲームには欠かせない「シーン」の意味と使い方を解説していきます。

シーンとは?

 enchan.jsには、「シーン」という概念があります。これはテレビドラマや映画におけるシーンの意味合いと同じく、その時々の場面を表す大きな塊のことを指します。

 enchant.jsにおいては、タイトル画面、ゲーム画面、ポーズ画面、ゲームオーバー画面など、「○○画面」と呼ばれる部分がシーンとして扱われます。以後、画面のことをシーンと呼びます。シーンの扱いを理解すると、開発がしやすくなるほか、メリハリのあるゲームを作れるようになります。

よくあるゲームの流れ(※次のサンプルではポーズ画面は実装していません)

サンプルプログラム

replaceScene
pushScene
popScene

 シーンと言われても、いまいちパッと浮かばないと思いますので、まずはサンプルをご覧ください。

サンプル

 実行すると、画面タッチで切り替わる、いくつかのシンプルな画面が表示されたと思います。この切り替わる画面1つ1つが独立したシーンで作られています。

 以下がサンプルプログラムです。やや長めですが、色分けされたブロックに注目してください。これらが各シーンとなるプログラムのまとまりになります。6〜35行目が新しくシーンを作っているところです。そして、16・31・48・54行目がシーンを切り替えているところです。

enchant();
window.onload = function() {
    var game_ = new Game(320, 320); // 表示領域の大きさを設定
    game_.fps = 24;                 // ゲームの進行スピードを設定
    game_.onload = function() {     // ゲームの準備が整ったらメインの処理を実行します
        /**
        * タイトルシーンを作り、返す関数
        */
        var createTitleScene = function() {
            var scene = new Scene();                // 新しいシーンを作る
            var label = new Label('タイトルシーン タッチでゲームシーンへ');   // 新しいラベル(文字)を作る
            scene.addChild(label);                  // シーンにラベルに追加
            scene.backgroundColor = 'rgba(255, 230, 0, 1)';      // シーンの背景色を設定
            scene.addEventListener(Event.TOUCH_START, function(e) { // シーンにタッチイベントを設定
                //現在表示しているシーンをゲームシーンに置き換えます
                game_.replaceScene(createGameScene());
            });
            // この関数内で作ったシーンを呼び出し元に返します(return)
            return scene;
        };
	/**
        * ゲームシーンを作り、返す関数
        */
        var createGameScene = function() {
            var scene = new Scene();                // 新しいシーンを作る
            var label = new Label('ゲームシーン タッチでゲームオーバーシーンを重ねる');        // 新しいラベル(文字)を作る
            scene.addChild(label);                  // シーンにラベルに追加
            scene.backgroundColor = 'rgba(255, 200, 0, 1)';      // シーンの背景色を設定
            scene.addEventListener(Event.TOUCH_START, function(e) { // シーンにタッチイベントを設定
                //現在表示しているシーンの上にゲームオーバーシーンを重ねて表示します
                game_.pushScene(createGameoverScene());
            });
            // この関数内で作ったシーンを呼び出し元に返します(return)
            return scene;
        };
        /**
        * ゲームオーバーシーンを作り、返す関数
        */
        var createGameoverScene = function() {
            var scene = new Scene();                // 新しいシーンを作る
            var label = new Label('ゲームオーバーシーン タッチでゲームシーンに戻る');      // 新しいラベル(文字)を作る
            label.x = 0;                            // 横位置調整
label.y = 20;                           // 縦位置調整
            scene.addChild(label);                  // シーンにラベルに追加
            scene.backgroundColor = 'rgba(0, 0, 255, 0.5)';      // シーンの背景色を設定
            scene.addEventListener(Event.TOUCH_START, function(e) { // シーンにタッチイベントを設定
                //現在表示しているシーンを外し、直前のシーンを表示します
                game_.popScene();
            });
            // この関数内で作ったシーンを呼び出し元に返します(return)
            return scene;
        };
        // ゲームの_rootSceneをタイトルシーンに置き換えます
        game_.replaceScene(createTitleScene());
        // このようにcreateTitleScene() と書くと、シーンが関数内で作成されて
        // createTitleScene()と書かれた場所に代入されます
    
}
    game_.start(); // ゲームをスタートさせます
};

※色の指定部分の補足

 このプログラム内で色の指定を行う部分に「rgba(〜)」という指定が出てきますが、16進数形式(例:#FCC800)のほかに、このように10進数形式でも色を指定できます。

rgba(赤, 緑, 青, 透明度);

 赤、緑、青は0から255までの10進数の整数を、不透明度は0.0(完全透明)〜1.0(完全不透明)の10進数の小数を指定できます。今回はシーンが重なっていることを強調するために半透明の色を使いたかったので後者の方法を使いました。

 以下のコードは、サンプルプログラムのうち、タイトルシーンに関わるところを抜き出したものです。このように、各画面に相当する部分を、他の画面からきれいに切り離して記述できるようになります。シーンの中身は、前回から今回にかけての内容を見ていれば、ほとんど理解できると思います。

        /**
        * タイトルシーンを作り、返す関数
        */
        var createTitleScene = function() {
            var scene = new Scene();                // 新しいシーンを作る
            var label = new Label('タイトルシーン タッチでゲームシーンへ');   // 新しいラベル(文字)を作る
            scene.addChild(label);                  // シーンにラベルに追加
            scene.backgroundColor = 'rgba(255, 230, 0, 1)';      // シーンの背景色を設定
            scene.addEventListener(Event.TOUCH_START, function(e) { // シーンにタッチイベントを設定
                //現在表示しているシーンをゲームシーンに置き換えます
                game_.replaceScene(createGameScene());
            });
            // この関数内で作ったシーンを呼び出し元に返します(return)
            return scene;
        };
……省略……
        // ゲームの_rootSceneをタイトルシーンに置き換えます
        game_.replaceScene(createTitleScene());
        // このようにcreateTitleScene() と書くと、シーンが関数内で作成されて
        // createTitleScene()と書かれた場所に代入されます

 ここでポイントとなるのは、このシーンのまとまりが関数として作られていることです。関数自体はenchant.jsの機能ではなく、JavaScriptの標準機能であるため詳しくは省きますが、今後使うときのためにコラムとして載せておきます。今は「こんな書き方をすれば動くんだー」くらいの認識でも構いません。

コラム 関数って何?

 「関数」とは現在のほとんどのプログラミング言語で使われている機能の1つで、使い方もさまざまです。

 ただ、enchant.jsの本稿のサンプルの使い方に限って言えば、「同じプログラムを使い回すための仕組み」だと思っていただいて構いません。

 関数とは、以下のようなものを指します。

 例えば、次のようなプログラムがあったとします。

処理1;
処理2;
処理3;

 このプログラムをいろいろなところで使いたい場合、そのまま書くと、次のようになります。

処理1
処理2
処理3
場所A
処理1
処理2
処理3
場所B
処理1
処理2
処理3
場所C

 このように、いくつもの場所に丸ごとコピーしなければなりません。

 そこで、この処理1〜3を関数としてまとめておくと、どの場所からも1行で同じ処理が実行できるようになります。

var 関数 = function() {
処理1
処理2
処理3
};どこかに書いておく
関数();
場所A
関数();
場所B
関数();
場所C

返数

 さらに、関数の中に「return 値」(「返数」といいます)というものを書くと、関数を実行したところにその値が代入される(返る)ようになります。

var 関数 = function() {
    処理1;
    処理2;
    処理3;
    return 値; // 変数といいます
}
var  a = 関数(); // 関数の中身が実行された後、aにreturnの値が入る
場所A(BもCも同じ)

引数

 さらに付け加えて、関数を作るときに()括弧の中に何かの値(「引数」といいます)を入れておくと、関数を呼び出すところから関数の中へと値を渡すことができるようになります。

var 関数の名前= function( atai /* 引数といいます */ ) {
var 変数 = atai;
処理1;
処理2;
処理3;
};
関数の名前(100); // 上の関数の中の「atai」に「100」が入った状態で処理が実行されます
場所A(BもCも同じ)

 このように、関数は1度宣言しておけば、さまざまな場所から呼び出して使うことができます。

 その他にも、「var 関数 = function() { }」と書くやり方とは別に「function 関数 () { } 」と書くやり方があり、性質がかなり異なるなど、JavaScriptには注意すべき点は多いのですが、ここでは省きます。難しく感じたときは、今は取りあえず「こう書けば動く」という認識だけでもOKです。詳しくはJavaScriptの入門書を参考にしてください。

ラベルについて

 Labelは初出ですが、テキストを扱うスプライトのようなものです。以下のメソッド以外は、ほぼスプライトと同じような扱いができます。

var ラベル名 = new Label(‘表示するテキスト’);
ラベル名.text = ‘表示するテキストを変更する’;
ラベル名.textAlign = ‘center’; // left: 左揃え center: 中央揃え right: 右端揃え

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。