読者です 読者をやめる 読者になる 読者になる

モーリーのメモ

プログラミングやCG作成等、アプリ開発を中心に情報を収集中!

マニュアルのチュートリアルをやってみる! その3(完):Cocos Creator

 こちらの記事の続きです。今回でチュートリアル完了です。
mmorley.hatenablog.com
 引き続き『Cocos Creator』の『User Manual』にあったチュートリアルの『Create the first game』をやってみます。
 今回も、スクリプトソースコード)の作成がメインです。
 ゲームが失敗した時のシーンのリロードや効果音の再生等の処理を追加しています。

使用環境

 私が使用している環境です。

  • Mac OS X El Capitan Version 10.11.4
  • Cocos Creator Version 1.0
  • ブラウザ:Google Chrome Version 49.0.2623.110 (64-bit)

スコアの追加

 リトルモンスターが星を採取するために多大な努力をします。しかし何故報酬を受けないのでしょうか?星を採取した際の得点のロジックと表示を追加します。

スコアのラベル(Label)を追加

 ゲームが開始されたとき、スコアは0からスタートします。星を1つ採取したら1点追加されます。スコアを表示するには、まず『Label』ノードを作成する必要があります。『Node Tree』パネルで『Canvas』ノード選択し、右クリックして『Create』-『Create Renderers』-『Label』を選択します。新しい『Label』ノードは『Canvas』の下に作成され、一番下に位配置されます。次にこの『Label』ノードを設定するために次の手順を使用します。

  1. ノードの名前を『score』に変更
  2. 『score』ノードの位置(『Position』プロパティ)を(0, 180)に設定
  3. 『score』コンポーネントの『Overflow』プロパティを『SHRINK』に設定
  4. 『score』ノードのサイズ(『Size』プロパティ)を(300, 80)に設定
  5. ノードを選択し、『Label』コンポーネントの『String』プロパティを編集し、『Score: 0』を入力
  6. 『score』コンポーネントの『Font Size』プロパティを50に設定
  7. 『Assets』パネルからビットマップフォントリソースの『assets/mikado_outline_shadow(注意!アイコンはf:id:mmorley:20160406161702p:plainです。)』を『Label』コンポーネントの『File』プロパティにドラッグし、フォントをビットマップフォントに入れ替えて下さい。

 
 完了すると次のようになります。
f:id:mmorley:20160408231859p:plain

『Game』スクリプトに得点のロジックを追加

 『Game』スクリプトに、得点とスコア表示の更新のロジックを書きます。編集を開始するために『Game』スクリプトを開いて下さい。まず、『properties』のブロックの最後に、スコア表示用の『Label』を参照するためのプロパティを追加します。

// Game.js
    properties: {
        // ...省略
        // 『score』ラベルを引用
        scoreDisplay: {
            default: null,
            type: cc.Label
        },
    },

 『Canvas』ノードの『Score Display』プロパティに『Node Tree』パネルから『score』ノードをドラッグします。
f:id:mmorley:20160415131740p:plain:w550
 次に、『onLoad』メソッドで得点用の変数を初期化を追加します。

// Game.js
    onLoad: function () {
        // ...省略
        // 得点を初期化
        this.score = 0;
    },

 それから『update』メソッドの後ろに『gainScore』と名付けたメソッドを新たに追加します。

// Game.js
    gainScore: function () {
        this.score += 1;
        // scoreDisplay(Label)のテキストを更新
        this.scoreDisplay.string = 'Score: ' + this.score.toString();
    },

 『Game』スクリプトを保存した後、『Star』スクリプトを開いて、『onPicked』メソッドに『gainScore』の呼び出しを追加します。

// Star.js
    onPicked: function() {
        // 星が採取された時に、新しく星を生成するために『Game』スクリプトでインターフェースを呼び出します。
        this.game.spawnNewStar();
        // 『Game』スクリプトの得点用のメソッドを呼び出します。
        this.game.gainScore();
        // その後、現在の『star』ノードを破棄します。
        this.node.destroy();
    },

 保存した後、プレビューします。星を採取した時、画面の上部に表示されたスコアが加算されます。
f:id:mmorley:20160408232828p:plain:w300

失敗の判定とリスタート

 ゲームが形になりました。しかし、どんなに多く得点が取れても、失敗の可能性のないゲームでは、プレイヤー満足感が得られません。星が規則的に消える動きを追加します。そして全ての星が消えた場合、ゲームは失敗したとみなされます。言い換えると、プレーヤーは、『play』メソッドのループを終えるために、星が消える前に星を採取し終えるという手順を絶え間なく繰り返す必要があります。

制限時間内に消えるロジックを星に追加

 『Game』 スクリプトを開いて、『onLoad』メソッドのspawnNewStar『spawnNewStar』を呼び出す前に時間のカウントに必要な変数の宣言を追加します。

// Game.js
    onLoad: function () {
        // 『ground』のアンカーポイントのy座標を取得
        this.groundY = this.ground.y + this.ground.height/2;
        // タイマーを初期化
        this.timer = 0;
        this.starDuration = 0;
        // 新しい星を生成
        this.spawnNewStar();
        // 得点を初期化
        this.score = 0;
    },

 それから、『spawnNewStar』メソッドの最後にタイマーをリセットするロジックを追加して下さい。『this.minStarDuration』と『this.maxStarDuration 』は冒頭で定義した『Game』コンポーネントのプロパティです。それらは星の持続時間の乱数の幅を規定するのに使用されます。

// Game.js
    spawnNewStar: function() {
        // ...省略
        // タイマーをリセットし、星の持続時間の幅に従ってランダムに値を選択
        this.starDuration = this.minStarDuration + cc.random0To1() * (this.maxStarDuration - this.minStarDuration);
        this.timer = 0;
    },

 タイマーの更新と持続時間を超えているか判定を行うロジックを『update』メソッドに追加します。

// Game.js
    update: function (dt) {
        // 持続時間を超えた後に新しい星が生成されない場合、フレームごとにタイマーを更新
        // ゲーム失敗のロジックを呼び出す
        if (this.timer > this.starDuration) {
            this.gameOver();
            return;
        }
        this.timer += dt;
    },

 最後に、『gameOver』メソッドを追加します。失敗した場合に、シーンをリロードします。

// Game.js
    gameOver: function () {
        this.player.stopAllActions(); // 『Player』ノードのジャンプのアクションを停止
        cc.director.loadScene('game');
    },

 『Game』スクリプトの変更は完了です。スクリプトを保存し、『Star』スクリプトを開いて下さい。星が消える際に、星に単純で素早い視覚効果を追加します。次のコードを『update』メソッドの最後に追加します。

// Star.js
    update: function() {
        // ...省略
        // 『Game』スクリプト内のタイマーに応じて星の透明度を更新
        var opacityRatio = 1 - this.game.timer/this.game.starDuration;
        var minOpacity = 50;
        this.node.opacity = minOpacity + Math.floor(opacityRatio * (255 - minOpacity));
    },

 『Star』スクリプトを保存してください。このゲームのプレイメソッドのロジックは完成しました。今すぐプレビューボタンをクリックしてください。ブラウザに、コアとなるプレイメソッド、刺激的なメカニズム、失敗のメカニズムによって装飾されたゲームが表示されます。

効果音を追加

 スマートフォンのゲームする時、多くの人が音を無視しますが、このチュートリアルでは完全なワークフローを提示するために、効果音を追加する作業を捕捉する必要があります。

ジャンプの効果音

 最初に、ジャンプの効果音を追加します。『Player』スクリプトを開いて、サウンドドキュメントリソースを引用するために『jumpAudio』プロパティを追加して下さい。

// Player.js
    properties: {
        // ...省略
        // ジャンプの効果音のリソース
        jumpAudio: {
            default: null,
            url: cc.AudioClip
        },
    },

 それから『setJumpAction』メソッドを書き換えて下さい。効果音を再生するコールバックを挿入し、『playJumpSound』メソッドを追加することで音を再生します。

// Player.js
    setJumpAction: function () {
        // ジャンプアップ
        var jumpUp = cc.moveBy(this.jumpDuration, cc.p(0, this.jumpHeight)).easing(cc.easeCubicActionOut());
        // ジャンプダウン
        var jumpDown = cc.moveBy(this.jumpDuration, cc.p(0, -this.jumpHeight)).easing(cc.easeCubicActionIn());
        // アクションが終わった後に、他の定義されたメソッドを呼び出すためのコールバック関数を追加
        var callback = cc.callFunc(this.playJumpSound, this);
        // 絶えず繰り返し実行、毎回着地の後に音を再生するためにコールバックを呼び出す
        return cc.repeatForever(cc.sequence(jumpUp, jumpDown, callback));
    },

    playJumpSound: function () {
        // 音を再生するサウンドエンジンを呼び出す
        cc.audioEngine.playEffect(this.jumpAudio, false);
    },

得点時の効果音

 『Player』スクリプトを保存した後、得点時の効果音を追加するために『Game』スクリプトを開きます。まず、サウンドドキュメントリソースを引用するためのプロパティを『properties』に追加します。

// Game.js
    properties: {
        // ...省略
        // 得点の効果音のリソース
        scoreAudio: {
            default: null,
            url: cc.AudioClip
        }
    },

 それから『gainScore』メソッドに音を再生するコードを挿入します。

// Game.js
    gainScore: function () {
        this.score += 1;
        // scoreDisplay(Label)のテキストを更新
        this.scoreDisplay.string = 'Score: ' + this.score.toString();
        // 得点の効果音を再生
        cc.audioEngine.playEffect(this.scoreAudio, false);
    },

 スクリプトを保存して下さい。『Node Tree』パネルに戻り、『Player』ノードを選択して、『assets/audio/jump』リソースを『Assets』パネルから『Player』コンポーネントの『Jump Audio』プロパティにドラッグします。
 
 それから『Canvas』ノードを選択して、『 assets/audio/score』リソースを『Game』コンポーネントの『Score Audio』プロパティにドラッグします。
 
 これで完了です。完成した『Node Tree』とキーとなるコンポーネントのプロパティは次のようになります。
f:id:mmorley:20160408234254p:plain
 
f:id:mmorley:20160408234315p:plain
 これで新しく作成したゲームを完全に楽しむことが出来ます。いくら得点出来ますか?ゲームの難易度を素早く調整するために、いつでも『Player』および『Game』コンポーネントで移動のコントロールや星の持続時間等といったゲームパラメータを変更出来ることを忘れないで下さい。コンポーネントのプロパティを変更した後、シーンノードを保存する必要があります。保存された値だけが記録されます。

概要

 おめでとうございます!『Cocos Creator』によって作られる最初のゲームが完成しました。我々は、この初心者のためのクイックスタートチュートリアルが、『Cocos Creator』のゲーム開発プロセスにおける基本的な概念とワークフローを理解するのに役立つことを願っています。もし、スクリプトプログラミングを書いたり学んだりすることに興味がなければ、完成版のプロジェクトから完成されたスクリプトを直接コピー&ペーストすることが出来ます。
 
 次に、あなたはこのゲームを仕上げ続けることができます。以下はおすすめの改善方法です。

  • シンプルなスタートメニューを追加します。ゲーム開始時にスタートボタンを表示します。ボタンをクリックした場合のみ、ゲームが開始します。
  • ゲーム失敗時のシンプルなメニューを追加します。失敗した後にボタンをクリックした場合のみ、ゲームが再開します。
  • メインキャラクタの移動範囲をウインドウの境界までに制限します。
  • 主人公のジャンプのアクションにもっと凝ったアニメーションのパフォーマンスを追加します。
  • 星が消えた時の状態表示にカウントダウンのプログレスバーを追加します。
  • 星を採取した時にもっと豪華なエフェクトを追加します。
  • タッチスクリーンデバイス向けの入力コントロールを追加します。

 
 上記のすべての面の改善がなされるために、ここで詳細には触れませんが、参考および学習用の進化版プロジェクトをダウンロードできます。
 
 さらに、友人と共有するためにサーバーで完成したゲームをリリースした場合は、『Preview Build』セクションの内容を読んで下さい。
 
 今日のチュートリアルはここで終了します。あなたはすぐに2つ目の『Cocos Creator』ゲームの作成を始めることも、このガイドを読み続けることも出来ます。このクイックスタートチュートリアルに関する質問は、『Github』のこのチュートリアルの倉庫にフィードバックすることが出来ます。
 
エンジンの使用経験に応じて、読み続けて下さい。
 
Cocos2d-xのユーザガイド

あとがき

 『Cocos Creator』のエディタの機能や、シーンの作成方法、スクリプトの書き方等を理解するのに役立ちました。
 たまにある独特の言い回しは、原文のせいです。クセがすごい。