モーリーのメモ

アプリ開発等(プログラミング、CG作成)、興味を持ったことを実践してまとめるブログです。

モーリーのメモ

マリオみたいな2Dアクションゲームを作る! その13 ビットマップフォントでスコア等を表示する:Cocos Creator

 ◆ Cocos Creatorスーパーマリオみたいな2Dアクションゲームを作ります。◆
 ◆ このシリーズの他の記事を見るには『PlatformerGame』タグをクリックして下さい。◆
 ◆ 最初から読みたい場合はココをクリックして下さい。◆
 
 こちらの記事の続きです。

 
 今回は、前回作成したビットマップフォントを使ってスコア・ライフ・ステージ番号を表示します。
 またコインを取得した時、敵を倒した時にスコアが加算される処理を追加します。
    f:id:mmorley:20200515115743p:plain
 
【 注意 】Cocos Creator v2.3.3は、VS Codeデバッグ実行でブレークポイントが機能しないバグがあので、v.2.3.2を使用して下さい。
 v.2.3.2は、Cocos DashboardのEditorのDownloadボタンからインストール出来ます。
 既存のプロジェクトのEditor Versionは、下図のように切り替えます。一度確認のメッセージが表示されます。
    f:id:mmorley:20200422191834p:plain

使用環境

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

スコア用のラベルを設置する

 スコアは常に画面に表示するのでカメラノードに設置します。
 スコアノードの位置合わせには、『Widgetコンポーネントを使います。
 『Widgetコンポーネントを使うと、ターゲットのノード(ここではカメラノード)を基準にして位置を決めることが出来ます。
 

    Cocos Creatorで作業

  1. 『Node Tree』パネルで『Main Camera』を選択して、『Properties』パネルで『Node』の『サイズ』を下図のように設定します。
    カメラノードのサイズを『Canvas』ノードと同じにします。
    カメラノードは『Widgetコンポーネントのターゲットにするのでサイズを設定する必要があります。
    f:id:mmorley:20200513110623p:plain
  2. 『Node Tree』パネルで『Main Camera』を右クリック→『Create』→『Create Renderer Nodes』→『Node With Label』をクリックしてノードを作成し、名前を”score”にします。
    f:id:mmorley:20200513114341p:plain
  3. 『Node Tree』パネルで『score』を選択して、『Assets』パネルの『assets/font/UI(Bfのアイコン)』を『Properties』パネルの『Label』の『Font』にドラッグ&ドロップします。
    f:id:mmorley:20200513154221p:plain
  4. 『Properties』パネルの『Label』を下図のように設定します。
    • String:Score:0000000
    • Horizontal Align:RIGHT
    • Font Size:20
    • Line Height:20
    f:id:mmorley:20200513144140p:plain
  5. 『Properties』パネルの『Add Component』→『UIComponent』→『Widget』をクリックします。
    f:id:mmorley:20200513144856p:plain
  6. 『Properties』パネルの『Widget』を下図のように設定します。
    『Target』を指定していない場合(nullの場合)は現在の親ノードが『Target』になります。
    • Top:チェックを入れて、値を10にします。
    • Right:チェックを入れて、値を15にします。
    f:id:mmorley:20200513212040p:plain

ステージ番号用のラベルを設置する

 現在のステージ番号を表示するためのラベルです。
 

    Cocos Creatorで作業

  1. 『Node Tree』パネルで『score』を右クリック→『Duplicate』をクリックして複製し、名前を"stageNo"にします。
    f:id:mmorley:20200513221527p:plain
  2. 『Node Tree』パネルで『stageNo』を選択して、『Properties』パネルの『Label』を下図のように設定します。
    • String:Stage:0
    • Horizontal Align:LEFT
    f:id:mmorley:20200513230451p:plain
  3. 『Properties』パネルの『Widget』を下図のように設定します。
    • Right:チェックを外します。
    • Left:チェックを入れて、値を15にします。
    f:id:mmorley:20200513230928p:plain

残りライフ用のラベルを設置する

 プレイヤーの残りのライフを表示するためのラベルです。
 

    Cocos Creatorで作業

  1. 『Node Tree』パネルで『stageNo』を右クリック→『Duplicate』をクリックして複製し、名前を"life"にします。
    f:id:mmorley:20200513221527p:plain
  2. 『Node Tree』パネルで『life』を選択して、『Properties』パネルの『Label』を下図のように設定します。
    • String:Life:0
    f:id:mmorley:20200514094937p:plain
  3. 『Properties』パネルの『Widget』を下図のように設定します。
    • Top:値を45にします。
    • Left:値を15にします。
    f:id:mmorley:20200514095133p:plain

スコア・ライフ・ステージ番号の処理を追加する

 スコア・ライフ・ステージ番号のラベルへの表示を行います。
 コインを取得した時、敵を倒した時にスコアを取得する処理を追加します。
 それぞれで獲得するスコアは、列挙型で定義します。
 
 TypeScriptでは"既存の型を組み合わせた新しい型"を定義することが出来ます。
 ここでは、スコア・ライフ・ステージ番号をまとめたPlayData型を定義します。
 スコア・ライフ・ステージ番号は、ステージを読み込む際に引き継ぐデータなので、扱いやすいようにまとめておきます。
 

    Cocos Creatorで作業

  1. 『Assets』パネルで『assets/script/player』をダブルクリックします。
    VS Codeが起動します。

    VS Codeで作業

  2. 『PlayData(型)』と『Score(列挙型)』を追加します。
    ファイルの先頭(Playerクラスの外)で定義します。

    // 独自の型を宣言する
    type PlayData = { // プレイ中のデータ(次のステージに引き継ぐデータ)
        score: number; // スコア
        life: number; // 残りのライフ
        stageNo: number; // ステージ番号
    }
    
    // 列挙型を定義する
    const enum Score { // スコアの定義
        CoinGold = 100, // coinGoldを取得した時の点数
        SlimeBlue = 200 // slimeBlueを倒した時の点数
    }
    
    const {ccclass, property} = cc._decorator;
    
    @ccclass
    export default class Player extends cc.Component { // クラス名をNewClassからPlayerにする
        /* 省略 */
    

  3. 各ラベルノードの取得、セッターとゲッターの設定、初期値の設定を行います。
     各ラベルのノードを取得して変数に格納します。
     ラベルの中身のデータとしてPlayData型の変数を定義し、それぞれに初期値を設定します。
     各データのセッターとゲッターを定義します。セッターでは数値を文字列に変換する処理も行います。
     『start()』で、各ラベルに初期値を表示します。
     

        update (dt: number) { // 毎フレームの描画前の処理(dt:前フレームからの経過時間)
        /* 省略 */
        }
    
        @property(cc.Label) // Cocos Creatorのエディタに表示する
        scoreLabel: cc.Label = null; // スコアのラベルを取得する
        @property(cc.Label) // Cocos Creatorのエディタに表示する
        stageNoLabel: cc.Label = null; // ステージ番号のラベルを取得する
        @property(cc.Label) // Cocos Creatorのエディタに表示する
        lifeLabel: cc.Label = null; // ライフのラベルを取得する
        playData: PlayData = { score: 0, stageNo:1, life: 3 } // プレイデータに初期値を設定する
        get score (): number { // スコアのゲッター
            return this.playData.score; // 値を返す
        }
        set score (value: number) { // スコアのセッター
            this.playData.score = value; // 値を取得する
            this.scoreLabel.string = "Score:" + ("000000" + value.toString()).slice(-7); // ラベルに表示する
        }
        get life (): number { // ライフのゲッター
            return this.playData.life; // 値を返す
        }
        set life (value: number) { // ライフのセッター
            this.playData.life = value; // 値を取得する
            this.lifeLabel.string = "Life:" + ("0" + value.toString()).slice(-2); // ラベルに表示する
        }
        get stageNo (): number { // ステージ番号のゲッター
            return this.playData.stageNo; // 値を返す
        }
        set stageNo (value: number) { // ステージ番号のセッター
            this.playData.stageNo = value; // 値を取得する
            this.stageNoLabel.string = "Stage:" + ("0" + value.toString()).slice(-2); // ラベルに表示する
        }
        start () { // 初めてupdate()が実行されるの前の処理
            this.score = this.playData.score; // スコアを表示する
            this.stageNo = this.playData.stageNo; // ステージ番号を表示する
            this.life = this.playData.life; // ライフを表示する
        }
    

  4. 『onBeginContact ()』に、コインを取得した時とスライムを倒した時にスコアを取得する処理を追加します。

        onBeginContact (contact: cc.PhysicsContact,
            selfCollider: cc.PhysicsCollider, otherCollider: cc.PhysicsCollider) { // 接触開始時の処理
        /* 省略 */
            
            // 接触相手のノードごとの処理
            switch (otherCollider.node.name) { // 接触相手のノードの名前で処理を分岐する
                case "coinGold": // coinGoldの場合
                    otherCollider.node.getComponent('coin').getCoin(); // coinスクリプトのgetCoin()を実行する
                    this.score += Score.CoinGold; // スコアを取得する
                    break;
                case "slimeBlue": // slimeBlueの場合
                    if (isPlayerBottom) { // 足で踏んだ場合
                        otherCollider.node.getComponent('slimeBlue').hit(); // slimeBlueスクリプトのhit()を実行する
                        playerBody.linearVelocity = cc.v2(playerBody.linearVelocity.x, 500); // 踏んだ後に跳ねる
                        this.score += Score.SlimeBlue; // スコアを取得する
                    }
                    break; 
            }
        }
    

  5. 『ctrl + s』キーを押して、コードを保存します。

    Cocos Creatorで作業

  6. 『Node Tree』パネルで、『player』ノードを選択して、『Properties』パネルで『player』スクリプトが見えるようにします。
  7. 『Node Tree』パネルから『Properties』パネルの『player』に下記のようにノードをドラッグ&ドロップします。
    • 『Node Tree』パネルの『Canvas/Main Camera/score』→『Properties』パネルの『player』の『Score Label』
    • 『Node Tree』パネルの『Canvas/Main Camera/stageNo』→『Properties』パネルの『player』の『Stage No Label』
    • 『Node Tree』パネルの『Canvas/Main Camera/life』→『Properties』パネルの『player』の『Life Label』
    f:id:mmorley:20200515110450p:plain
  8. 『ctrl + p』キー(またはプレビューボタン)を押して、プレビューを実行します。
    ゲーム画面を一度クリックした後、プレイヤーをキー操作で移動出来ます。
    【 注意 】クリックでゲーム画面をフォーカスしていないとキー操作出来ません。
     
    *下図はgifです。クリックで再生します。(ブログの仕様でgifがループします。)
    *キーボードとマウスの操作を表示するソフトを使っています。

 

今回作成したファイル

 今回の作業によって下記のファイルのようになります。

 
 今回はここまでです。お疲れさまでした。