モーリーのメモ

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

モーリーのメモ

マリオみたいな2Dアクションゲームを作る! その7 タイルマップでステージを作る:Cocos Creator

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

 
 今回は、タイルマップでステージを作成します。
 タイルマップとは、タイルセット(マップチップ)と呼ばれる色々なパターンのタイルを並べて、ゲームのステージやマップを作成したものです。1つタイルセットで様々なステージが作成出来ます。
    f:id:mmorley:20200421224150p: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

使用環境

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

Tiledをインストールする

 Tiledをダウンロードしてインストールします。
 

    ブラウザで作業

  1. 下記のサイトを開きます。
    https://thorbjorn.itch.io/tiled
  2. 『Download Now』をクリックします。
    f:id:mmorley:20200421231616p:plain
    寄付を募る画面が出ます。
  3. ダウンロードだけする場合は、『No thanks, just take me to the downloads』をクリックします。
    f:id:mmorley:20200421232943p:plain
  4. 『Download』をクリックします。
    f:id:mmorley:20200421233306p:plain
    『Tiled-1.3.4-win64.msi』がダウンロードされます。
  5. 『Tiled-1.3.4-win64.msi』をダブルクリックして実行します。
  6. 『詳細情報』をクリックします。
    f:id:mmorley:20200421234726p:plain
  7. 『実行』をクリックします。
    f:id:mmorley:20200422000745p:plain
  8. 『Next』をクリックします。
    f:id:mmorley:20200422001151p:plain
  9. 『I accept the terms in the License Agreement』にチェックを入れて、『Next』をクリックします。
    f:id:mmorley:20200422001404p:plain
  10. インストール先を指定して、『Next』をクリックします。
    f:id:mmorley:20200422002315p:plain
  11. 『Install』をクリックします。
    f:id:mmorley:20200422001614p:plain
  12. 『このアプリがデバイスに変更を加えることを許可しますか?』と表示されたら、『はい』をクリックします。
  13. 『Finish』をクリックします。
    f:id:mmorley:20200422001946p:plain
 
 以上で、インストール完了です。

タイルセットの画像をAssetsに追加する

    Windows、Cocos Creatorで作業

  1. Windowsエクスプローラーで下記のフォルダ選択して、『Assets』パネルの『texture』にドラッグ&ドロップします。
    • Platformer Pack Redux (360 assets)\Spritesheets\spritesheet_ground.png
      その1で入手した画像素材ファイルです。
    f:id:mmorley:20200422010952p:plain

タイルマップを描く

 タイルセットの画像を並べてステージを作成します。
 

    Tiledで作業

  1. 『ファイル』→『新規』→『新しいタイルセット』をクリックします。
    f:id:mmorley:20200422063335p:plain
  2. 下図のように設定して、『ファイル名をつけて保存』をクリックします。
    • 『参照』をクリックして、Assetsに追加した『spritesheet_ground.png』を選択します。
    • 『タイルの幅』を"128px"にします。
    • 『タイルの高さ』を"128px"にします。
    f:id:mmorley:20200422064439p:plain
  3. 『assets/texture』フォルダにファイル名はそのままで『保存』をクリックします。
    f:id:mmorley:20200422065648p:plain
  4. 『ファイル』→『新規』→『新しいマップ』をクリックします。
    f:id:mmorley:20200422071445p:plain
  5. 下図のように設定して、『ファイル名をつけて保存』をクリックします。
    • マップの大きさの『幅』を"200タイル"にします。
    • マップの大きさの『高さ』を"20タイル"にします。
    • タイルの大きさの『幅』を"128px"にします。
    • タイルの大きさの『高さ』を"128px"にします。
    f:id:mmorley:20200422084624p:plain
  6. 『assets/texture』フォルダに”stage01.tmx”と名前を付けて『保存』をクリックします。
    Cocos Creatorのプロジェクトフォルダの『assets/texture』です。
    f:id:mmorley:20200422082600p:plain
  7. 『レイヤー』パネルで、レイヤー名をダブクリックして”tile”に変更します。
    問題ないかもしれませんが日本語を避けました。
    f:id:mmorley:20200422091140p:plain
  8. 『タイルセット』パネルで、タイルを選んでからマウスのドラッグで下図のように描きます。
    f:id:mmorley:20200422092414p:plain

タイルマップにオブジェクトを配置する

 Cocos Creatorでタイルマップを読み込む時に、オブジェクトの形状と位置の情報を元にコライダーを作成します。
 

    Tiledで作業

  1. 『レイヤー』パネルで、『新しいレイヤー』ボタン→『Object Layer』をクリックします。
    f:id:mmorley:20200422092844p:plain
  2. 作成したレイヤーの名前を”platform”に変更します。
    f:id:mmorley:20200425135045p:plain
  3. 『四角形を追加』ボタンをクリックして、『ctrl』キーを押しながらマウスでドラッグして下図のようにオブジェクトを作成します。
    オブジェクトを配置するにはオブジェクトレイヤーが選択されている必要があります。
    『ctrl』キーを押すと、マウスカーソルがグリッドに吸着します。
    f:id:mmorley:20200422094248p:plain
  4. 続けて下図のようにオブジェクトを配置します。
    f:id:mmorley:20200422095759p:plain

シーンにタイルマップを追加する

    Cocos Creatorで作業

  1. 『Assets』パネルから『stage01』を『Node Tree』パネルにドラッグ&ドロップします。
    子ノードも一緒に追加されます。
    f:id:mmorley:20200423075758p:plain
  2. 『Node Tree』パネルで『Canvas/stage01』を選択して、『Properties』パネルで『Node』を下図のように設定します。
    f:id:mmorley:20200422103851p:plain
  3. >『Node Tree』パネルで『Canvas/ground』を選択して、右クリック→『Delete』をクリックして削除します。

タイルマップのオブジェクトからコライダーを作る

 タイルマップで配置したオブジェクトの形状と位置の情報を元にコライダーを作成します。
 

    Cocos Creatorで作業

  1. 『Assets』パネルで『script』フォルダを右クリック→『Create』→『Typescript』をクリックします。
  2. 作成されたファイルの名前を"stage"に変更します。
    f:id:mmorley:20200423080450p:plain
  3. 『Node Tree』パネルで『Canvas/stage01』を選択して、『Properties』パネルで『Add Component』→『Custom Component』→『stage』をクリックして追加します。
    f:id:mmorley:20200422113445p:plain
  4. 『Assets』パネルで『assets/script/stage』をダブルクリックします。
    VS Codeが起動します。

    VS Codeで作業

  5. 下記のようにコードを変更します。

    const {ccclass, property} = cc._decorator;
    
    @ccclass
    export default class Stage extends cc.Component { // クラス名をNewClassからStageにする
    
        tiledMap: cc.TiledMap = null; // タイルマップ
        tiledMapSize: cc.Size = null; // タイルマップのサイズ
        start () {
            this.tiledMap = this.getComponent(cc.TiledMap); // stageノードの『TiledMap』コンポーネントを取得
            this.tiledMapSize = cc.size( // タイルマップのサイズを計算
                this.tiledMap.getTileSize().width * this.tiledMap.getMapSize().width, // タイルの幅 × x方向のタイルの枚数
                this.tiledMap.getTileSize().height * this.tiledMap.getMapSize().height); // タイルの高さ × y方向のタイルの枚数
    
            this.addPhisicsNode(); // コライダーを設置する
        }
    
        addPhisicsNode () { // 『Tiled』のオブジェクト情報を元にコライダーを配置
            let objects: any[] = this.tiledMap.getObjectGroup("platform").getObjects(); // 『Tiled』のplatformレイヤーのオブジェクトを取得
            let layerNode: cc.Node = this.tiledMap.node.getChildByName("platform"); // platformノードを取得
            let physicsNode: cc.Node = new cc.Node(); // コライダーを配置するノードを作成
            physicsNode.name = "platformCollider"; // ノード名を変更する
            let rigidBody: cc.RigidBody = physicsNode.addComponent(cc.RigidBody); // ノードにRigidBody(剛体)コンポーネントを追加
            rigidBody.type = cc.RigidBodyType.Static; // 剛体のタイプをスタティック(静的)にする
            for (let i = 0; i < objects.length; i ++) { // オブジェクトの数だけループ
                let curObject = objects[i]; // オブジェクトを取得
                let pos = cc.v2( // オブジェクトの位置をCocos Creatorの座標(中心が原点)に変換
                    curObject.offset.x + curObject.width / 2 - this.tiledMapSize.width / 2, // マップの幅/2オフセット
                    this.tiledMapSize.height / 2 - curObject.offset.y - curObject.height / 2); // マップの高さ/2オフセットし、正負逆転
                switch (curObject.type) { // タイプ別に処理をする
                    case 0: // ボックス, ポイント
                        let boxCollider: cc.PhysicsBoxCollider = physicsNode.addComponent(cc.PhysicsBoxCollider); // 物理ノードにボックスコライダーを追加して取得
                        boxCollider.name = curObject.name; // 名前を取得   
                        boxCollider.density = 0; // 密度
                        boxCollider.friction = 0; // 摩擦係数
                        boxCollider.restitution = 0; // 反発係数
                        boxCollider.size = cc.size(curObject.width, curObject.height); // ボックスのサイズ
                        boxCollider.offset = pos; // ボックスの中心位置
                        break;
                    case 1: // サークル
                        let circleCollider: cc.PhysicsCircleCollider = physicsNode.addComponent(cc.PhysicsCircleCollider); // 物理ノードにサークルコライダーを追加して取得
                        circleCollider.name = curObject.name; // 名前を取得
                        circleCollider.density = 0; // 密度
                        circleCollider.friction = 0; // 摩擦係数
                        circleCollider.restitution = 0; // 反発係数
                        circleCollider.radius = curObject.width / 2; // 円の半径
                        circleCollider.offset = pos; // 円の中心位置
                        break;
                    case 2: // ポリゴン
                        let polygonCollider:cc.PhysicsPolygonCollider = physicsNode.addComponent(cc.PhysicsPolygonCollider); // 物理ノードにポリゴンコライダーを追加して取得
                        polygonCollider.name = curObject.name; // 名前を取得
                        polygonCollider.density = 0; // 密度
                        polygonCollider.friction = 0; // 摩擦係数
                        polygonCollider.restitution = 0; // 反発係数
                        for (let j = 0; j < curObject.points.length; j ++) { // ポリゴンの頂点の数だけループ
                            polygonCollider.points[j] = cc.v2(curObject.points[j]); // ポリゴンコライダーに頂点をコピー
                        }
                        if (curObject.points.length == 3) { // 三角形の場合
                            polygonCollider.points[curObject.points.length] = polygonCollider.points[0]; // 最後に始点を入れてポリゴンを閉じる
                        }
                        
                        polygonCollider.offset = pos; // ポリゴンの始点
                        break;
                }
            }
            layerNode.addChild(physicsNode); // 物理ノードをstaticノードの子ノードとして追加
        }
    
    }
    

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

    Cocos Creatorで作業

  7. 『ctrl + p』キー(またはプレビューボタン)を押して、プレビューを実行します。
    ゲーム画面を一度クリックした後、プレイヤーをキー操作で移動出来ます。
    【 注意 】クリックでゲーム画面をフォーカスしていないとキー操作出来ません。
     
    *下図はgifです。クリックで再生します。(ブログの仕様でgifがループします。)
    *キーボードとマウスの操作を表示するソフトを使っています。

今回作成したファイル

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

 
 今回はここまでです。お疲れさまでした。
 
 続きは、こちらの記事です。