第6回 – PhaserでTiledを使ってみよう!(実装編)
前回の記事では、TiledのインストールとMAPデータを入手するところまでやりました。
今回は入手したデータからMAPを作成し、実際にPhaserでMAP上でプレイヤーを動かしてみます。
やっとここまでたどり着いた感じです。
MAP画像データをコピー
入手したデータのMAP画像データを自分の任意のプロジェクトにコピーします。
Tiledを起動します。
「新しいマップ」選択し、タイトルの型式、マップの大きさ、タイルの大きさを指定して、OKを押してください。
「新しいタイルセット」選択してください。
MAPをデザインします。
「レイヤー」を選択し、レイヤー名を入力します。この例では「maneo_layer」です。
MAPをjsonでエクスポートします。
MAPを保存します。
PhaserでMAPを描画させる
TiledでMAPデータを作成したので、このMAPをPhaserで描画させます。
// マップデータをロード
this.load.tilemapTiledJSON('map', 'assets/tiled/maneo/maneo.json');
this.load.image('maneo_tileset', 'assets/tiled/maneo/tilemap.png');
// ゲームのマップとタイルを設定
Game.map = this.make.tilemap({ key: 'map' });
Game.tiles = Game.map.addTilesetImage('maneo_tileset');
const layer = Game.map.createLayer('maneo_layer', Game.tiles, 0, 0);
// スケールを2倍にする
layer.setScale(2);
setCollisionでキャラクタと衝突させるタイルをタイル番号でセットします。
番号は、左から右にシーケンシャルに振られます。MAPの赤枠で囲まれた右側から一番最初が1でその後13のタイルをセットします。
// 衝突するタイルの設定
Game.map.setCollision([1, 13]);
// ゲームにレイヤーを追加
Game.layer = layer;
以上でやっとゲームらしくなってきましたね。
次回は、メニュー、スコアとか付けて、ちゃんと遊べるようにできるようがんばります!
以下、ソースコード全体を記載しておきます。
全体のコード
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Phaser Game</title>
<!-- Phaser ライブラリの読み込み -->
<script src="//cdn.jsdelivr.net/npm/phaser@3.70.0/dist/phaser.js"></script>
</head>
<body>
<!-- ゲームコンテナのスタイル -->
<style>
#canvas {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
border-radius: 5px;
}
</style>
<!-- ゲームコンテナ -->
<div id="canvas"></div>
<!-- ゲームスクリプト -->
<script>
// ゲームのデータを保持するオブジェクト
let Game = {};
// ゲームのシーンを表すクラス
class Scene extends Phaser.Scene {
constructor() {
super({
key: 'Scene'
});
}
// ゲーム開始前の事前準備(アセットのロード)を行うメソッド
preload() {
// マップデータをロード
this.load.tilemapTiledJSON('map', 'assets/tiled/maneo/maneo.json');
this.load.image('maneo_tileset', 'assets/tiled/maneo/tilemap.png');
// プレイヤーのスプライトシートをロード
this.load.spritesheet('player', './assets/player.png', {
frameWidth: 48,
frameHeight: 48
});
}
// ゲームの初期化およびオブジェクトの生成を行うメソッド
create() {
// ゲームのマップとタイルを設定
Game.map = this.make.tilemap({ key: 'map' });
Game.tiles = Game.map.addTilesetImage('maneo_tileset');
const layer = Game.map.createLayer('maneo_layer', Game.tiles, 0, 0);
// スケールを2倍にする
layer.setScale(2);
// 衝突するタイルの設定
Game.map.setCollision([1, 13]);
// ゲームにレイヤーを追加
Game.layer = layer;
// プレイヤーの追加
Game.player = this.physics.add.sprite(160, 0, 'player', 0);
Game.player.setSize(16, 48);
//Game.player.setScale(2);
// プレイヤーのアニメーション設定
this.anims.create({
key: 'right',
frames: this.anims.generateFrameNumbers('player', { start: 12, end: 14 }),
frameRate: 10,
repeat: -1
});
this.anims.create({
key: 'left',
frames: this.anims.generateFrameNumbers('player', { start: 6, end: 8 }),
frameRate: 10,
repeat: -1
});
// 衝突処理
this.physics.add.collider(Game.player, Game.layer, function (player, tile) {
// タイルに関する情報にアクセス
console.log('Player collided with tile:', tile);
// タイルのインデックスを取得
const tileIndex = tile.index;
console.log('Tile index:', tileIndex);
});
// カーソルキーのセットアップ
cursors = this.input.keyboard.createCursorKeys();
// デバッググラフィックスの設定
this.physics.world.debugGraphic = this.add.graphics();
this.physics.world.debugGraphic.setAlpha(0.5);
// 衝突タイルのデバッグ表示
Game.layer.renderDebug(this.physics.world.debugGraphic, {
tileColor: null,
collidingTileColor: new Phaser.Display.Color(243, 134, 48, 255),
faceColor: new Phaser.Display.Color(40, 39, 37, 255)
});
// プレイヤーのデバッグ表示
this.physics.world.debugGraphic.fillStyle(0xffff00, 0.9);
this.physics.world.debugGraphic.fillRect(Game.player.x, Game.player.y, Game.player.width, Game.player.height);
}
// ゲームの状態を更新するメソッド
update() {
// カーソルキーの入力に応じてプレイヤーを移動
if (cursors.left.isDown) {
Game.player.setVelocityX(-160);
Game.player.anims.play('left', true);
} else if (cursors.right.isDown) {
Game.player.setVelocityX(160);
Game.player.anims.play('right', true);
} else {
Game.player.setVelocityX(0);
}
// UPキーでplayerが地面に接しているとき
if (cursors.up.isDown && Game.player.body.onFloor()) {
// プレイヤーが地面に触れているときだけジャンプする
Game.player.setVelocityY(-400);
// プレイヤーを白くする。
Game.player.setTint(0xffffff);
}
}
}
// ゲームの設定情報を格納するオブジェクト
let config = {
type: Phaser.AUTO,
parent: 'canvas',
width: 32*14,
height:11*20,
pixelArt: true,
roundPixels: false,
antialias: false,
physics: {
default: 'arcade',
arcade: {
debug: true,
gravity: {
y: 600
}
}
},
scene: [Scene]
};
// ゲームオブジェクトの作成
let game = new Phaser.Game(config);
// カーソルキーの状態を保持する変数
let cursors;
// ウィンドウのリサイズイベントに対するリスナー
window.addEventListener('resize', function () {
// キャンバスのサイズを更新
game.canvas.width = window.innerWidth;
game.canvas.height = window.innerHeight;
game.renderer.resize(window.innerWidth, window.innerHeight);
});
</script>
</body>
</html>