キャッシュを無視してページをリロードする。
そうだったのか・・・
60pxの市松模様で10行、10列(縦横600px)の画像があったとします。
これを中心に配置すると以下のようになります。
./src/main.js
import Phaser from "phaser";
import GameScene from "./scenes/GameScene";
const config = {
type: Phaser.AUTO,
width: 1200,
height: 600,
parent: 'game-container',
backgroundColor: '#fff',
scale: {
mode: Phaser.Scale.NONE,
autoCenter: Phaser.Scale.CENTER_BOTH
},
dom: {
createContainer: true
},
scene: [
GameScene
]
};
export default new Phaser.Game(config);
./src/scenes/GameScene.js
import { Scene } from 'phaser';
export default class GameScene extends Phaser.Scene {
constructor() {
super('GameScene');
}
preload() {
this.load.image("bg", "./assets/bg.png");
}
create() {
const centerX = this.scale.width / 2;
const centerY = this.scale.height / 2;
const bg = this.add.image(centerX, centerY, "bg");
bg.setOrigin(0.5);
}
update() {
}
}

そのうち、左上を基準に、2行、4列(縦120px × 横240px)を表示しようとしてcropを使うと
./src/scenes/GameScene.js
import { Scene } from 'phaser';
export default class GameScene extends Phaser.Scene {
constructor() {
super('GameScene');
}
preload() {
this.load.image("bg", "./assets/bg.png");
}
create() {
const centerX = this.scale.width / 2;
const centerY = this.scale.height / 2;
const bg = this.add.image(centerX, centerY, "bg");
bg.setOrigin(0.5);
const cropX = 0;
const cropY = 0;
const cropWidth = 240;
const cropHeight = 120;
bg.setCrop(cropX, cropY, cropWidth, cropHeight);
}
update() {
}
}

setOriginはあくまでも全体のサイズにおけるセンターのため、
切り取った部分をセンターにもっていくためには、調整が必要。
./src/scenes/GameScene.js
import { Scene } from 'phaser';
export default class GameScene extends Phaser.Scene {
constructor() {
super('GameScene');
}
preload() {
this.load.image("bg", "./assets/bg.png");
}
create() {
const centerX = this.scale.width / 2;
const centerY = this.scale.height / 2;
const width = 600;
const height = 600;
// 切り取り領域
const cropX = 0;
const cropY = 0;
const cropWidth = 240;
const cropHeight = 120;
const bg = this.add.image(centerX + (width - cropWidth) / 2, centerY + (height - cropHeight) / 2, "bg");
bg.setOrigin(0.5);
bg.setCrop(cropX, cropY, cropWidth, cropHeight);
}
update() {
}
}

どちらかというと、原点をセンターにするより、左上の位置から調整した方が楽ですね。
create() {
const centerX = this.scale.width / 2;
const centerY = this.scale.height / 2;
// 切り取り領域
const cropX = 0;
const cropY = 0;
const cropWidth = 240;
const cropHeight = 120;
const bg = this.add.image(centerX - cropWidth / 2, centerY - cropHeight / 2, "bg");
bg.setOrigin(0);
bg.setCrop(cropX, cropY, cropWidth, cropHeight);
}
1つの画像に同一サイズの画像をまとめているのであれば、SpriteSheetを使って切り出してつかうことができます。
↓縦横20pxのデータが8つある。
./src/scenes/GameScene.js
import { Scene } from 'phaser';
export default class GameScene extends Phaser.Scene {
constructor() {
super('GameScene');
}
preload() {
this.load.spritesheet("charList", "./assets/CharList.png", { frameWidth: 20, frameHeight: 20 });
}
create() {
const charList = [];
for (let n = 0; n < 8; n++) {
const row = 20 * Math.trunc(n / 4);
const col = 20 * (n % 4);
const char = this.add.image(col, row, "charList", n);
char.setOrigin(0); // 原点は左上
charList.push(char);
}
}
update() {
}
}
↓左上から2行4列で表示
ボタンや、表といったものは、Phaserでは用意していないのでHTMLを追加することになります。
例えば、タイトル画面でゲーム開始ボタンを用意し、ゲーム画面に遷移するとします。
button要素一つ追加する例
DOMを追加する場合、configに dom : { createContainer : true } を追加する必要があります。
./src/main.js
import { AUTO, Scale, Game } from 'phaser';
import GameScene from './scenes/GameScene';
import TitleScene from './scenes/TitleScene';
// Find out more information about the Game Config at:
// https://newdocs.phaser.io/docs/3.70.0/Phaser.Types.Core.GameConfig
const config = {
type: AUTO,
width: 960,
height: 540,
parent: 'game-container',
backgroundColor: '#FFF',
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH
},
scene: [
TitleScene,
GameScene
],
dom: {
createContainer: true
},
};
export default new Game(config);
./src/scenes/TitleScene.js
import { Scene } from 'phaser';
export default class TitleScene extends Scene {
constructor() {
super('TitleScene');
}
preload() {
}
create() {
const centerX = this.scale.width / 2;
const centerY = this.scale.height / 2;
const btnStartNode = document.createElement("button");
btnStartNode.className = "btnStart btnStart--royalblue";
btnStartNode.innerText = "ゲーム開始";
btnStartNode.addEventListener("click", () => { this.scene.start("GameScene"); });
const btnStart = this.add.dom(centerX, centerY, btnStartNode);
}
update() {
}
}
./src/scenes/GameScene.js
import { Scene } from 'phaser';
export default class GameScene extends Scene {
constructor() {
super('GameScene');
}
preload() {
}
create() {
}
update() {
}
}
./public/phaser.css
.btnStart {
border: none;
border-radius: 5px;
color: white;
font-size: 200%;
padding: 10px 30px;
text-align: center;
}
.btnStart--royalblue{
background-color: royalblue;
border-bottom: 5px solid rgb(48, 66, 133);
}
.btnStart--royalblue:hover {
background: rgb(85, 125, 245);
border-bottom: 2px solid rgb(48, 66, 133);
margin-top: 2px;
}

タイトル画面で、ゲームの種類を選択して画面遷移させたい場合など、複数の同一のボタンを用意したい場合
複数のボタンを追加する例
今度は、ボタンのクラスを作って配置してみます。
./src/main.js
import { Scene } from 'phaser';
import GameTypeButton from '../objects/GameTypeButton'
export default class TitleScene extends Scene {
constructor() {
super('TitleScene');
}
preload() {
}
create() {
const centerX = this.scale.width / 2;
const centerY = this.scale.height / 2;
new GameTypeButton(this, centerX - 90, centerY, "Game1", () => { this.scene.start("GameScene"); });
new GameTypeButton(this, centerX + 0, centerY, "Game2", () => { this.scene.start("GameScene2"); });
new GameTypeButton(this, centerX + 90, centerY, "Game3", () => { this.scene.start("GameScene3"); });
}
update() {
}
}
./scenes/TitleScene.js
import { Scene } from 'phaser';
import GameTypeButton from '../objects/GameTypeButton'
export default class TitleScene extends Scene {
constructor() {
super('TitleScene');
}
preload() {
}
create() {
const centerX = this.scale.width / 2;
const centerY = this.scale.height / 2;
new GameTypeButton(this, centerX - 90, centerY, "Game1", () => { this.scene.start("GameScene"); });
new GameTypeButton(this, centerX + 0, centerY, "Game2", () => { this.scene.start("GameScene2"); });
new GameTypeButton(this, centerX + 90, centerY, "Game3", () => { this.scene.start("GameScene3"); });
}
update() {
}
}
DOMを追加するクラスは、Phaser.GameObjects.DOMElementを継承します。
ここでは、親クラスには、scene, x, y, HTML要素を渡しています。
./src/objects/GameTypeButton.js
export default class GameTypeButton extends Phaser.GameObjects.DOMElement {
constructor(scene, x, y, text, callback) {
// HTML要素を作成
const element = document.createElement('button');
element.innerText = text;
element.className = "btnStart btnStart--royalblue";
super(scene, x, y, element);
// シーンに追加
scene.add.existing(this);
// ボタンクリック時のコールバックを設定
this.node.addEventListener('click', callback);
}
}
./public/phaser.css
.btnStart {
border: none;
border-radius: 5px;
color: white;
font-size: 100%;
padding: 5px 15px;
text-align: center;
}
.btnStart--royalblue{
background-color: royalblue;
border-bottom: 5px solid rgb(48, 66, 133);
}
.btnStart--royalblue:hover {
background: rgb(85, 125, 245);
border-bottom: 2px solid rgb(48, 66, 133);
margin-top: 2px;
}
./srcscenes/GameScene.js
import { Scene } from 'phaser';
export default class GameScene extends Scene {
constructor() {
super('GameScene');
}
preload() {
}
create() {
}
update() {
}
}
./srcscenes/GameScene2.js
import { Scene } from 'phaser';
export default class GameScene2 extends Scene {
constructor() {
super('GameScene2');
}
preload() {
}
create() {
}
update() {
}
}
./srcscenes/GameScene3.js
import { Scene } from 'phaser';
export default class GameScene3 extends Scene {
constructor() {
super('GameScene3');
}
preload() {
}
create() {
}
update() {
}
}

大した、Styleじゃないので、CSSファイルにわけるのではなく、ソースとStyle一か所でまとめて管理したいというのであれば・・・
親クラスにStyleも渡す場合
cssに記載していた内容をクラス内にまとめるとすると・・・
./src/objects/GameTypeButton.js
export default class GameTypeButton extends Phaser.GameObjects.DOMElement {
constructor(scene, x, y, text, callback) {
const style = {
backgroundColor: "royalblue",
border: "none",
borderBottom: "5px solid rgb(48, 66, 133)",
borderRadius: "5px",
color: "white",
fontSize: "100%",
marginTop: "0px",
padding: "5px 15px",
textAlign: "center",
};
super(scene, x, y, "button", style, text);
this.setOrigin(0.5);
scene.add.existing(this);
// ボタンクリック時のコールバックを設定
this.node.addEventListener('click', callback);
// ホバー設定(over/outで代用)
this.node.addEventListener('mouseover', () => {
this.node.style.background = "rgb(85, 125, 245)";
this.node.style.borderBottom = "2px solid rgb(48, 66, 133)";
this.node.style.marginTop = "2px";
});
this.node.addEventListener('mouseout', () => {
this.node.style.background = style.backgroundColor
this.node.style.borderBottom = style.borderBottom;
this.node.style.marginTop = style.marginTop;
});
}
}
ランキングのようなものとかなら、templateタグで用意しておいてゲーム画面外の要素として表示とかでよい気がする。
最近の投稿
最近のコメント
タグ
アーカイブ
その他
- ▶ ()