Phaser3+typescriptでSRPGを開発してみる #004 マップ作成
こんにちは!
次に着手したいのが、まずは動くものを作りたい、ということでタイルチップの読み込みです。
タイルチップとは、昔ながらの2D(3Dもそうかもですが)ゲームを作るときのバックの絵のことです。 スーパーマリオのブロックとか、ドラクエの地図マップとか、そんなイメージで、 SRPG作るときにもまず必要になりそうな気がします。
マップ作成(1)
マップのタイルチップ
まずはタイルチップを取得して画像ファイルを読み込みます。
今回は、ドット絵世界、から草原のタイルチップをお借りしてまいりました。 yms.main.jp
画像ファイル(png等)はpreload()関数の中で読み込みます。
this.load.image("PLAIN_MAP", "/images/map/tileset_demo.png");
preload()関数は、Phaser3のフレームワークが順次呼び出すライフサイクル関数のうちの一つです。
ライフサイクル
Phaser.Sceneクラスを継承したクラスは、下記メソッドを呼び出せます。
関数名 | 概要 |
---|---|
init | preloadに先駆けて呼ばれるメソッド。どんな場合に使うのかはもう少し確認が必要 |
preload | アセット(画像・音楽・データ等)を呼び出すときに使用 |
create | シーンスタート時にゲームオブジェクトを作るときに使用 |
update | シーンに対して更新を掛けるときに使用。FPSの指定タイミング間隔でよびだされる |
initのタイミングだけはよくわからず、今後サンプルとか見てみようと思いますが、 その他のpreload、create、updateの3関数を使いこなせれば、ゲームは作れそうです。
では、GameScene.tsを修正してみます。
GameScene.ts
export default class GameScene extends Phaser.Scene { // 1セルあたりの解像度(px) public static CELL_PX = { WIDTH : 32, HEIGHT : 32 }; // マップの開始位置 private static MAP_POSITION = { X : 20, Y : 40 }; // タイルセットの画像ファイルのキー private static TILESET_KEY_PLAIN = "PLAIN_MAP"; preload() { // 画像ファイルをロード(キー・ファイルパス) this.load.image(GameScene.TILESET_KEY_PLAIN, "/images/map/tileset_demo.png"); } create() { // マップデータの指定(タイルチップの番号) let mapData: number[][] = [ [3, 3, 3, 3, 3, 3, 3, 3, 3, 3], [3, 3, 3, 3, 3, 3, 3, 3, 3, 3], [3, 3, 3, 3, 3, 3, 3, 3, 3, 3], [3, 3, 3, 3, 3, 3, 3, 3, 3, 3], [3, 3, 3, 3, 3, 3, 3, 3, 3, 3] ]; // タイルマップの作成 var tilemap = this.make.tilemap({ data: mapData, // マップデータ tileWidth: GameScene.CELL_PX.WIDTH, // タイルの単位幅(px) tileHeight: GameScene.CELL_PX.HEIGHT // タイルの単位高さ(px) }); // タイルセットをリンク付け let planeTiles = tilemap.addTilesetImage(GameScene.TILESET_KEY_PLAIN); // 一番下のレイヤーを作成 // 第3引数・第4引数は、左上の座標を(0,0)とした時の配置位置(x,y) let mapGroundLayer = tilemap.createLayer( 0, planeTiles, GameScene.MAP_POSITION.X, GameScene.MAP_POSITION.Y); } }
TilemapConfig
this.make.tilemap()
の引数がTilemapConfigです。
dataには、配置したいマップのデータを配列でセットします。
mapData
変数にて定義していますが、今回は全て3
を指定してます。
こうすると、画像ファイルの左上から3番目(と言いながら、0番目から開始するので、実質左から4番目)が呼ばれます。
この画像ファイルは32×32を1セルとして構成されています。その指定が、tileWidth
とtileHeight
です。
今回は、クラス内部の定数として定義してみました(この辺りが、古いJavaプログラマーの発想なのかも)。
ちなみに、画像ファイルの場所が誤っていると、
Invalid Tileset Image: PLAIN_MAP
というエラーが出ます。
より複雑なマップに
今回は全て3
にしましたが、試しに湖を中に作ってみようとしますと、
let mapData: number[][] = [ [3, 3, 3, 3, 3, 3, 3, 3, 3, 3], [3, 3, 3, 3, 26, 11, 27, 3, 3, 3], [3, 3, 3, 3, 11, 11, 11, 3, 3, 3], [3, 3, 3, 3, 42, 11, 43, 3, 3, 3], [3, 3, 3, 3, 3, 3, 3, 3, 3, 3] ];
なんか不格好ですよね。。
まあ、湖の中の黒部分はさっきの画像を0.5個分、ずらしたタイルマップを作ればいけそうです。
ただ、縁の部分はそうはいかないです。。画像ファイルは透過対応してくれるのですが、一番下の背景が真っ黒ですからね。。
もしかしたらレイヤー化したら変わるかも?とも思い、create()の記載を、Layer ID:0用とID:1用を続けてプログラミングしてみたのですが、この結果は無情にもID:0用しか反映されず、草原のみ表示。わざわざID:1用の配置位置をtilemapLayer1.createLayer(1, planeTiles1, 20,200);
と重ならないようにy軸をずらしたのに。。
エラーを見ると
Invalid Tilemap Layer ID: 1
。単に認識されていないようです。。
では、このLayer IDはどこで指定しているのか?
Phaser3のソースコード(OSSなので。。)の中身を見てみると、どうやら、
- デフォルトでtilemapを読み込むと、number型の0が入る
var index = this.getLayerIndex(layerID); if (index === null) { console.warn('Invalid Tilemap Layer ID: ' + layerID);
- tilemap読み込むときにLayerIDを指定する? といった特徴がありそう。。
そんな中、マップ作成を支援してくれそうなソフトの存在も発見!
すみません、、後半(#005)へ続きます。 mtmusic34.hatenablog.com
過去の日記
タイトル | 記載内容 | |
---|---|---|
#001 | プロローグ | Phaser3とは |
#002 | 環境設定 | インストール・ビルド環境設定 |
#003 | はじめてのPhaser3 | 初回稼働・キャンバス表示 |