第4回 – Phaserゲームでキャラクターと車の衝突検出
Phaserを使用したゲーム開発では、キャラクターとオブジェクトの衝突検出は非常に重要です。この記事では、Phaserを使ってプレイヤーキャラクターが車と衝突した際にどのように処理するかを解説します。
キャラクターと車の作成
プレイヤーキャラクターと車を作成します。プレイヤーキャラクターは物理エンジンを有効にし、アニメーションも追加します。
// プレイヤーキャラクターの作成
player = this.physics.add.sprite(frame_width / 2, frame_height / 2, 'player');
this.physics.world.enable(player);
// アニメーションの追加
this.anims.create({
key: 'right',
frames: this.anims.generateFrameNumbers('player', { start: 12, end: 14 }),
frameRate: 10,
repeat: -1
});
// 他の設定...
// 車の作成
cars = this.physics.add.sprite(car_x, car_y, 'car');
this.physics.world.enable(cars);
// 他の設定...
衝突処理の実装
プレイヤーキャラクターと車の衝突処理は以下のように実装します。衝突が検出された場合、プレイヤーを赤く変色させる例です。
// 衝突処理
function collisionHandler(player, car) {
console.log('Player collided with car!');
// プレイヤーを赤く変色
player.setTint(0xff0000);
}
// 衝突検出の設定
this.physics.add.collider(player, cars, collisionHandler, null, this);
ゲームの更新処理
最後に、ゲームの更新処理を実装します。これにはキャラクターの移動や、画面外に出た車を再度配置する処理が含まれます。
function update(time, delta) {
// キャラクターの移動処理...
// 画面外に出たら再度右から出現
if (!cars_stop) {
cars.setVelocityX(-100);
if ((cars.x - cars.width) <= 0) {
cars.setX(car_x);
}
}
}
以上で、Phaserゲームでのキャラクターと車の衝突検出が実装されました。これにより、ゲーム内での衝突に対する処理が正しく行われ、臨場感あふれるゲームプレイが実現できます。
全体のコード
<!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>
#game-container {
margin: auto 0;
padding: 0;
}
#game-container {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
#game-container canvas {
border-radius: 5px;
}
</style>
<!-- ゲームコンテナ -->
<div id="game-container"></div>
<!-- ゲームスクリプト -->
<script>
// ウィンドウスケールの設定
let window_scale = 0.9;
if (window.innerWidth > 800)
window_scale = 0.5;
// フレームの初期値
let frame_width = window.innerWidth * window_scale;
let frame_height = 400;
let car_x = frame_width;
let car_y = frame_height - 30;
// Phaser ゲームの設定
const config = {
type: Phaser.AUTO,
width: frame_width,
height: frame_height,
backgroundColor: "#222222",
parent: "game-container",
physics: {
default: 'arcade',
arcade: {
gravity: { y: 600 }, // 重力の設定
debug: false // デバッグ表示の有無
}
},
scene: {
// ゲームの事前読み込み処理
preload: preload,
// ゲームの初期化処理
create: create,
// ゲームのフレームごとの更新処理
update: update
}
};
// Phaser ゲームの作成
const game = new Phaser.Game(config);
// プレイヤーのスプライト
let player;
// カーソルのキー
let cursors;
// 車のスプライト
let cars;
// 車の停止
let cars_stop = false;
// ゲームの事前読み込み処理
function preload() {
// 画像などのリソースの基本URLを設定
this.load.setBaseURL("https://honda-workshop.com/works/phaser/");
// 背景画像の読み込み
this.load.image("backgroud", "/assets/city.png");
// プレイヤーのスプライトシートの読み込み
this.load.spritesheet('player', '/assets/player.png', { frameWidth: 48, frameHeight: 48 });
// 車の画像の読み込み
this.load.image("car", "./assets/car.png");
}
// ゲームの初期化処理
function create() {
// ゲームの幅と高さを取得
const { width, height } = this.sys.game.config;
// 背景スプライトの作成
const bg = this.add.tileSprite(0, 0, width, height, "backgroud");
bg.setOrigin(0, 0);
// プレイヤーのスプライトを作成
player = this.physics.add.sprite(frame_width / 2, frame_height / 2, 'player');
// プレイヤースプライトに物理エンジンを有効にする
this.physics.world.enable(player);
// プレイヤースプライトにアニメーションを追加
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
});
// プレイヤースプライトに物理エンジンの設定
player.body.setBounce(0.1);
player.body.setCollideWorldBounds(true);
// カーソルのキーを有効にする
cursors = this.input.keyboard.createCursorKeys();
// アニメーションの再生
player.anims.play('right', true);
// 車のスプライトを作成
cars = this.physics.add.sprite(car_x, car_y, 'car');
cars.setBounce(0.0);
cars.setCollideWorldBounds(true);
// 車のスプライトに物理エンジンの設定
cars.body.setSize(32, 28, true); // 車の余白を考慮した設定
// 車に物理エンジンを有効にする
this.physics.world.enable(cars);
// プレイヤーと車の衝突処理
this.physics.add.collider(player, cars, collisionHandler, null, this);
}
// 衝突処理
function collisionHandler(player, car) {
console.log('Player collided with car!');
// プレイヤーを赤くする。
player.setTint(0xff0000);
}
// ゲームのフレームごとの更新処理
function update(time, delta) {
// カーソルキーの入力に応じてプレイヤーを移動
if (cursors.left.isDown) {
player.setVelocityX(-160);
player.anims.play('left', true);
} else if (cursors.right.isDown) {
player.setVelocityX(160);
player.anims.play('right', true);
} else {
player.setVelocityX(0);
}
// UPキーでplayerが地面に接しているとき
if (cursors.up.isDown && player.body.onFloor()) {
// プレイヤーが地面に触れているときだけジャンプする
player.setVelocityY(-400);
// プレイヤーを白くする。
player.setTint(0xffffff);
}
cars.setVelocityX(-100);
// 画面外に出たら再度右から出現
if ( (cars.x - cars.width) <= 0) {
cars.setX(car_x);
}
}
// ウィンドウのリサイズ時の処理
window.addEventListener('resize', function () {
// ゲームの幅と高さをリサイズ
frame_width = window.innerWidth * window_scale;
frame_height = 200;
console.log(frame_width);
console.log(frame_height);
game.scale.resize(frame_width, frame_height);
// プレイヤースプライトの位置をリサイズ後に更新
player.setPosition(frame_width / 2, frame_height / 2);
});
</script>
</body>
</html>