Phaserで始めるゲーム開発入門

1.2K Views

January 21, 23

スライド概要

2023/01/21に開催されたBurikaigi 2023で発表したセッション資料の公開版です。
こちらのチュートリアルについての理解をお話しさせていただきました。
https://phaser.io/tutorials/making-your-first-phaser-3-game/part1

profile-image

Developer Evangelist @ Twilio

シェア

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

Phaserで始める ゲーム開発入門 2023/01/21 池原大然 (@Neri78) #burikaigi #burikaigi_s

2.

自己紹介 池原 大然 Twilio デベロッパーエバンジェリスト Twitter: @neri78 趣味はゲーム(エンジョイ勢) #burikaigi #burikaigi_s

3.

あらためて #burikaigi #burikaigi_s

4.

エンジョイ勢です #burikaigi #burikaigi_s

5.

Phaserとは? オープンソースで開発されているHTML5ゲームフレームワーク https://phaser.io/ #burikaigi #burikaigi_s

6.

Q.なぜこの話をするのか? #burikaigi #burikaigi_s

7.

A. ゲーマーだから #burikaigi #burikaigi_s

8.

ではなく #burikaigi #burikaigi_s

9.

仕事でも(すこし)関わっているから 日本語版: https://www.twilio.com/quest/ja English Ver: https://www.twilio.com/quest/ #burikaigi #burikaigi_s

10.

Phaserの種類 Phaserのバージョンは2つ ● Phaser 3 開発チームが開発を主導している最新バージョン ● Phaser 2 / CE (Community Edition) コミュニティに開発が委ねられた旧バージョン #burikaigi #burikaigi_s

11.

セッションでカバーする内容 チュートリアルを自分なりに理解したものを共有する 自分は「Phaser完全に理解した」状態 ● ● ● ● ● ● Phaserの導入方法 ゲームの実行方法 アセットのロードと画面への配置方法 物理エンジンの利用方法 キーボードナビゲーションの設定方法 オブジェクト同士が衝突した際の処理方法 #burikaigi #burikaigi_s

12.

今日の題材 https://phaser.io/learn #burikaigi #burikaigi_s https://phaser.io/tutorials/making-your-first-phaser-3-game/part1

13.

完成品 #burikaigi #burikaigi_s

14.

Phaserの導入 #burikaigi #burikaigi_s

15.

利用するもの 参考: https://phaser.io/tutorials/getting-started-phaser3 ● JavaScript ● Webサーバー ● コードエディター #burikaigi #burikaigi_s

16.

参照方法 - https://phaser.io/download/stable ● ローカルjsファイル ● npm npm install [email protected] ● CDN <script src="//cdn.jsdelivr.net/npm/[email protected]/dist/phaser.js"></script> <script src="//cdn.jsdelivr.net/npm/[email protected]/dist/phaser.min.js"></script> #burikaigi #burikaigi_s

17.

参照 <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Making your first Phaser 3 Game</title> <script src="//cdn.jsdelivr.net/npm/[email protected]/dist/phaser.js"></script> </head> <body> <script type="text/javascript"> …ロジックの実装 </script> </body> </html> #burikaigi #burikaigi_s

18.

ゲームの起動 #burikaigi #burikaigi_s

19.
[beta]
基本構造
<script type="text/javascript">
// 設定を定義
let config = {
type: Phaser.AUTO, // レンダリングコンテキストの指定 - AUTO, CANVAS, WEBGL
width: 800, // ゲーム画面のキャンバス幅
height: 600, // ゲーム画面のキャンバス高さ
scene: { // 画面設定
preload: preload, // 画面ロード前に実行されるロジック
create: create, // 画面作成時に実行されるロジック
update: update // 更新時に実行されるロジック
}
};
// ゲームを作成
let game = new Phaser.Game(config);

#burikaigi #burikaigi_s
</script>

20.

画像の読み込み方法 #burikaigi #burikaigi_s

21.

画像たち #burikaigi #burikaigi_s

22.

画面作成前に画像アセットをロード // 画面作成前に実行。呼び出し元はPhase.Sceneクラス function preload () { // Sceneに組み込まれているPhaser.Loader.LoaderPluginを使用し、アセットを読み込み // 画像の読み込み(key, source) this.load.image('sky', 'assets/sky.png'); this.load.image('ground', 'assets/platform.png'); this.load.image('star', 'assets/star.png'); this.load.image('bomb', 'assets/bomb.png'); } #burikaigi #burikaigi_s

23.

画面作成時にアセットを配置 // シーン開始時にScene Managerによって呼び出される。 // ScenePlugin.add()、ScenePlugin.start()、Scene.settings.dataでデータを渡せる // 呼び出し元はPhaser.Scene function create () { // 画像を追加 // Phaserはアセットの中心を (0,0)に設置してしまうので座標計算が必要 this.add.image(400, 300, 'sky'); // あるいはsetOriginを使用 this.add.image(0,0, 'sky').setOrigin(0,0); // 画像は下から順にスタックされていく this.add.image(400, 300, 'star'); } #burikaigi #burikaigi_s

24.

ゲームオブジェクトの 設置方法 #burikaigi #burikaigi_s

25.
[beta]
物理演算エンジンの指定
let config = {
type: Phaser.AUTO, width: 800, height: 600,
// 物理演算エンジンを指定
physics: {
default: 'arcade', //デフォルト物理演算システム arcade, impact, matter
arcade: {
gravity: { y: 300 },
debug: false
}
},
scene: { // 省略
}

#burikaigi #burikaigi_s
};

26.

動的オブジェクト (動かしたい) 静的オブジェクト (動かさない) #burikaigi #burikaigi_s

27.

静的オブジェクト (動かさない) #burikaigi #burikaigi_s

28.

静的オブジェクト(動かないもの)の作成 let platforms; function create () { // 静的な物理オブジェクトグループの作成 platforms = this.physics.add.staticGroup(); // Phaser.Physics.Arcade.StaticGroup.create(x,y, key) // スケーリングをする場合は再描画を指示 platforms.create(400, 568, 'ground').setScale(2).refreshBody(); platforms.create(600, 400, 'ground'); platforms.create(50, 250, 'ground'); platforms.create(750, 220, 'ground'); } #burikaigi #burikaigi_s

29.

動的オブジェクト (動かしたい) #burikaigi #burikaigi_s

30.
[beta]
動的オブジェクトを追加
function preload ()
{
// スプライトシート( key, source, オプション )
this.load.spritesheet('dude', 'assets/dude.png', { frameWidth: 32, frameHeight: 48 });
}
let player;
function create ()
{
// 動的なオブジェクトを追加。 this.physics.add - Dynamics Physics / 左下から 100 x 450ピクセルにスプライトを配置
player = this.physics.add.sprite(100, 450, 'dude');
// オブジェクトの弾み方
player.setBounce(0.2);
// 世界の境界線と衝突させるかどうか
player.setCollideWorldBounds(true);
// プレイヤースプライトと静的オブジェクトの間に衝突を追加
this.physics.add.collider(player, platforms);

}
#burikaigi
#burikaigi_s

31.

スプライトシートとは? 複数の画像を1枚の画像にまとめたもの 0 1 #burikaigi #burikaigi_s 2 3 4 5 6 7 8

32.
[beta]
スプライトシートからアニメーションを定義
function create ()
{
this.anims.create({

this.anims.create({
key: 'left',

key: 'turn',

frames: this.anims.generateFrameNumbers(

frames: [ { key: 'dude', frame: 4 } ],
frameRate: 20

'dude', { start: 0, end: 3 }),
});

frameRate: 10,
repeat: -1

this.anims.create({

});

key: 'right',
frames: this.anims.generateFrameNumbers(

this.anims.create({

'dude', { start: 5, end: 8 }),

key: 'turn',
frameRate: 10,

frames: [ { key: 'dude', frame: 4 } ],

repeat: -1

frameRate: 20
});

#burikaigi #burikaigi_s

});
}

33.

オブジェクトを 操作できるようにする #burikaigi #burikaigi_s

34.

キーボードの入力を検知し、 指定の方向に移動させる #burikaigi #burikaigi_s

35.

オブジェクトの移動に利用できそうなもの Phaser . Physics . Arcade . Sprite - https://newdocs.phaser.io/docs/3.55.2/Phaser.Physics.Arcade.Sprite ● ● ● ● ● setVelocity, setVelocityX, setVelocityY - 速度を設定 setAcceleration, setAccelerationX, setAccelerationY - 加速度を設定 setAngle - 角度を設定 setAngularAcceleration - 角速度を設定 setPosition - 位置を設定 #burikaigi #burikaigi_s

36.
[beta]
キーボード入力の定義

else if (cursors.right.isDown)
{

let player;

// X軸(右方向)に対して160の加速度を付与 = 右

let cursors;

player.setVelocityX(160);
// プレイヤーオブジェクトの外観を変更
player.anims.play('right', true);

function create ()
}

{
// カーソルキー(Up, Down, Left, Right)を作成

else

cursors = this.input.keyboard.createCursorKeys();

{

}

// その他のキーの場合は左右移動を停止させる

function update ()

player.setVelocityX(0);

{

player.anims.play('turn');
// キーが押された方向を感知し、処理を追加

}

if (cursors.left.isDown)
if (cursors.up.isDown && player.body.touching.down)

{
// X軸(右方向)に対して-160の加速度を付与 = 左移動

{

player.setVelocityX(-160);

// Y軸(下方向)に対して-330の加速度を付与 = 上移動

// プレイヤーオブジェクトの外観を変更

player.setVelocityY(-330);

#burikaigi #burikaigi_s

}

player.anims.play('left', true);

}

}

37.

オブジェクト同士の 衝突制御 #burikaigi #burikaigi_s

38.

別のオブジェクトに衝突した 場合をどう検知する? #burikaigi #burikaigi_s

39.

プレイヤーと別の動的オブジェクト let starts; function create () { // 指定のオブジェクトの衝突判定をおこなわせる this.physics.add.collider(player, platforms); this.physics.add.collider(stars, platforms); // playerとstartsが重なりあった(衝突した)際の処理を定義 this.physics.add.overlap(player, stars, collectStar, null, this); } function collectStar (player, star) { // スターの表示を無効化させる star.disableBody(true, true); #burikaigi #burikaigi_s }

40.

スコアを画面に表示 #burikaigi #burikaigi_s

41.

スターに触れた際に 得点を追加したい #burikaigi #burikaigi_s

42.
[beta]
スコアを画面に追加し、加算する
let score = 0;
let scoreText;

function create ()
{
// スコアテキストの追加
scoreText = this.add.text(16, 16, 'score: 0', { fontSize: '32px', fill: '#000' });
}

function collectStar (player, star)
{
// スターの表示を無効化させる
star.disableBody(true, true);
// スコアを増加させ、テキストを更新
score += 10;
scoreText.setText('Score: ' + score);

}
#burikaigi
#burikaigi_s

43.

ゲームを停止させる #burikaigi #burikaigi_s

44.

爆弾に触れた際に ゲームを停止 #burikaigi #burikaigi_s

45.

爆弾を追加し、衝突時にゲームを停止させる let bombs; let gameOver = false; function create () { // 爆弾を追加 bombs = this.physics.add.group(); // Collide the player and the stars with the platforms this.physics.add.collider(bombs, platforms); // プレーヤーと星が重なった際のイベントハンドリング(また使う) this.physics.add.overlap(player, stars, collectStar, null, this); // プレイヤーと爆弾が衝突した際のイベントをハンドリング #burikaigi #burikaigi_s } this.physics.add.collider(player, bombs, hitBomb, null, this);

46.
[beta]
爆弾の生成と衝突時の処理
function collectStar (player, star)

function hitBomb (player, bomb)

{

{
// 星が全てなくなった時点で星を再生成し、爆弾を生成する

// 物理エンジンを一時停止

if (stars.countActive(true) === 0)

this.physics.pause();

{

// プレイヤーの色合いを追加で設定
stars.children.iterate(function (child) {

player.setTint(0xff0000);
child.enableBody(true, child.x, 0, true, true); });

// turnアニメーションを実行
player.anims.play('turn');

let x = (player.x < 400) ? Phaser.Math.Between(400, 800) :

// flag

Phaser.Math.Between(0, 400);

gameOver = true;
let bomb = bombs.create(x, 16, 'bomb');
bomb.setBounce(1);
bomb.setCollideWorldBounds(true);
bomb.setVelocity(Phaser.Math.Between(-200, 200), 20);
bomb.allowGravity = false;

#burikaigi #burikaigi_s
}

}

}

47.

まとめ・リソース #burikaigi #burikaigi_s

48.

まとめ JavaScriptでゲームを作成できる 物理演算エンジンを提供 慣れるまで大変そう (デモできなかった)別のツールで作成した タイルをロードすることもできる ● スポンサーLTで追加のデモをする予定! ● ● ● ● #burikaigi #burikaigi_s

49.

ありがとうございました! #burikaigi #burikaigi_s