Phaser 3 | タイルマップ作成と衝突処理

2020-09-13未分類

タイルマップ作成と衝突処理

Phaser3でTiledを利用してタイルマップ作成・生成するメモです。

Phaser3のタイルマップ処理はTiledで作成したマップデータに対応しており、なおかつ実装情報が多い方なので、タイルマップを使ったゲームを作成するにはTiledを利用するのがおすすめです。

動作サンプルと環境

Tiledで作成したマップデータを使った動作サンプルです。

このサンプルではプレイヤーキャラは動きません。

See the Pen Phaser 3 Tile Map Sample by yochans (@yochans) on CodePen.

動作サンプルの環境は、Phaser 3.20.1のCDNを利用しています。

Tiledの設定

Tiledを利用する場合、基本的には普通に新規マップ、タイルセットを追加、レイヤー分けしながらマップを作成して、JSONファイルで保存してタイルセットと一緒に指定のディレクトリに配置して使うことが可能です。

レイヤー名

Phaser3での呼び出し時に、レイヤー名の指定ではなく0からの連番でも可能ですけど、複数レイヤーを使うことを想定すると「ground」などのレイヤー名を設定しておいた方が無難です。

保存形式

マップデータのファイルはJSONで保存。設定はデフォルトのままでも問題なく使えます。

Phaser3のコード

Phaser3ではpreloadでマップチップ画像とマップデータファイルを読み込んで、createなどで生成して使います。

プリロード

マップチップ画像とマップデータをプリロードするサンプルコードです。

サンプルでは、マップチップ画像は「tileset」、マップデータは「map」というキー名を指定しています。

preload() {
	this.load.tilemapTiledJSON('map', 'map.json');
	this.load.image('tileset', 'tileset.png');
}

タイルマップ生成

プリロードしたキー名を使ってタイルマップを作成するサンプルコードです。

サンプルではマップデータにある「ground」というレイヤーのマップをcreateStaticLayer()で生成しています。

複数のレイヤーがある場合は、別途createStaticLayer()を使って追加します。

create() {
	let map = this.scene.make.tilemap({ key: 'map' });
	let tiles = map.addTilesetImage('tiles', 'tileset');
	let ground = Game.map.createStaticLayer( 'ground', tiles);
}

プレイヤーなどとの衝突処理の追加

上記サンプルで作ったレイヤーを対象にプレイヤーなどとの接地処理は壁などとの衝突処理を実装するサンプルコードです。

サンプルではプレイヤーオブジェクトが作成済みのものとして記述しています。

create() {
	let map = this.scene.make.tilemap({ key: 'map' });
	let tiles = map.addTilesetImage('tiles', 'tileset');
	let ground = Game.map.createStaticLayer( 'ground', tiles);

	//groundレイヤーに物理制御
	ground.setCollisionByExclusion(-1, true);

	//プレイヤーとgroundレイヤーの衝突処理
	this.physics.add.collider(player, ground);
}

動作サンプルの全コード

※上記サンプルコードとは違って、create内で作成している各変数をGameの中に入れています。

//Scene
class Scene extends Phaser.Scene {

	constructor() {
		super({
			key: 'Scene'
		});
	}

	preload() {
		//マップデータをロード
		this.load.tilemapTiledJSON('map', 'https://raw.githubusercontent.com/Yousuke777/files/master/phaser-tilemap/map.json');
		this.load.image('tileset', 'https://raw.githubusercontent.com/Yousuke777/files/master/phaser-tilemap/tiles.png');

		//プレイヤー
		this.load.spritesheet('player', 'https://raw.githubusercontent.com/Yousuke777/files/master/phaser-tilemap/player.png', {
			frameWidth: 16,
			frameHeight: 24
		});
	}


	create() {
		let Game = {};
		//利用するマップデータとタイルセットを指定
		Game.map = this.make.tilemap({
			key: 'map'
		});
		Game.tiles = Game.map.addTilesetImage('tiles', 'tileset');

		//レイヤー別にマップを生成
		Game.background = Game.map.createStaticLayer('background', Game.tiles);
		Game.ground = Game.map.createStaticLayer('ground', Game.tiles);
		Game.obj = Game.map.createStaticLayer('obj', Game.tiles);

		//groundに物理制御
		Game.ground.setCollisionByExclusion(-1, true);

		//プレイヤー
		Game.player = this.physics.add.sprite(160, 132, 'player', 0);

		//衝突処理
		this.physics.add.collider(Game.player, Game.ground);

		//カメラ
		Game.mainCamera = this.cameras.main;
		Game.mainCamera.startFollow(Game.player);
		Game.mainCamera.setZoom(3);
	}
}



//config
let config = {
	type: Phaser.AUTO,
	parent: 'canvas',
	width: 600,
	height: 300,
	//Pixel Perfect用
	pixelArt: true,
	roundPixels: false,
	antialias: false,
	physics: {
		default: 'arcade',
		arcade: {
			debug: false,
			gravity: {
				y: 300
			}
		}
	},
	scene: [Scene]
};

//game
let game = new Phaser.Game(config);

2020-09-13未分類

Posted by Yousuke.U