Add BootScene and MenuScene, update game initialization and UI
- Import and register new `BootScene` and `MenuScene` in `main.js`. - Create `BootScene` to generate all shared textures once at startup and then start the menu. - Implement full-featured `MenuScene` with background asteroids, wandering alien, title, controls panel, and start button (including ENTER key support). - Remove texture generation logic and helper from `GameScene`; it now relies on textures created by `BootScene`. - Change game‑over handling to return to the menu instead of restarting the game.
This commit is contained in:
parent
33d340ef10
commit
9a40e9a23a
|
|
@ -1,3 +1,5 @@
|
||||||
|
import BootScene from './scenes/BootScene.js';
|
||||||
|
import MenuScene from './scenes/MenuScene.js';
|
||||||
import GameScene from './scenes/GameScene.js';
|
import GameScene from './scenes/GameScene.js';
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
|
|
@ -12,7 +14,7 @@ const config = {
|
||||||
debug: false
|
debug: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scene: [GameScene]
|
scene: [BootScene, MenuScene, GameScene]
|
||||||
};
|
};
|
||||||
|
|
||||||
new Phaser.Game(config);
|
new Phaser.Game(config);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
// BootScene – runs once at startup to generate all shared textures, then hands
|
||||||
|
// off to MenuScene. Textures live in Phaser's global TextureManager so every
|
||||||
|
// subsequent scene can use them without re-creating them.
|
||||||
|
|
||||||
|
export default class BootScene extends Phaser.Scene {
|
||||||
|
constructor() {
|
||||||
|
super({ key: 'BootScene' });
|
||||||
|
}
|
||||||
|
|
||||||
|
create() {
|
||||||
|
this._createTextures();
|
||||||
|
this.scene.start('MenuScene');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Texture Generation ───────────────────────────────────────────────────
|
||||||
|
|
||||||
|
_createTextures() {
|
||||||
|
// Player ship – 64×32, nose points right (angle 0)
|
||||||
|
let g = this.make.graphics({ add: false });
|
||||||
|
g.lineStyle(2, 0x00ff44, 1);
|
||||||
|
g.strokeTriangle(56, 16, 12, 4, 12, 28);
|
||||||
|
g.generateTexture('player', 64, 32);
|
||||||
|
g.destroy();
|
||||||
|
|
||||||
|
// Player ship with thruster flame
|
||||||
|
g = this.make.graphics({ add: false });
|
||||||
|
g.lineStyle(2, 0x00ff44, 1);
|
||||||
|
g.strokeTriangle(56, 16, 12, 4, 12, 28);
|
||||||
|
g.lineStyle(2, 0xff6600, 1);
|
||||||
|
g.strokeTriangle(12, 11, 12, 21, 0, 16);
|
||||||
|
g.generateTexture('player_thrust', 64, 32);
|
||||||
|
g.destroy();
|
||||||
|
|
||||||
|
// Large asteroid – 120×120, radius 50, 12-sided
|
||||||
|
g = this.make.graphics({ add: false });
|
||||||
|
g.lineStyle(2, 0xcccccc, 1);
|
||||||
|
g.strokePoints(this._asteroidPoints(60, 60, 50, 12,
|
||||||
|
[1.0, 0.82, 1.08, 0.88, 1.0, 0.78, 1.1, 0.9, 0.94, 1.0, 0.84, 1.06]
|
||||||
|
), true);
|
||||||
|
g.generateTexture('asteroid_large', 120, 120);
|
||||||
|
g.destroy();
|
||||||
|
|
||||||
|
// Medium asteroid – 64×64, radius 26, 10-sided
|
||||||
|
g = this.make.graphics({ add: false });
|
||||||
|
g.lineStyle(2, 0xcccccc, 1);
|
||||||
|
g.strokePoints(this._asteroidPoints(32, 32, 26, 10,
|
||||||
|
[1.0, 0.78, 1.1, 0.88, 1.0, 0.82, 1.0, 0.92, 1.06, 0.80]
|
||||||
|
), true);
|
||||||
|
g.generateTexture('asteroid_medium', 64, 64);
|
||||||
|
g.destroy();
|
||||||
|
|
||||||
|
// Small asteroid – 32×32, radius 12, 8-sided
|
||||||
|
g = this.make.graphics({ add: false });
|
||||||
|
g.lineStyle(2, 0xcccccc, 1);
|
||||||
|
g.strokePoints(this._asteroidPoints(16, 16, 12, 8,
|
||||||
|
[1.0, 0.78, 1.12, 0.84, 1.0, 0.9, 0.80, 1.04]
|
||||||
|
), true);
|
||||||
|
g.generateTexture('asteroid_small', 32, 32);
|
||||||
|
g.destroy();
|
||||||
|
|
||||||
|
// Alien saucer – 64×48
|
||||||
|
g = this.make.graphics({ add: false });
|
||||||
|
g.lineStyle(2, 0x00ffff, 1);
|
||||||
|
g.strokeEllipse(32, 30, 52, 20);
|
||||||
|
g.strokeEllipse(32, 22, 30, 18);
|
||||||
|
g.generateTexture('alien', 64, 48);
|
||||||
|
g.destroy();
|
||||||
|
|
||||||
|
// Player bullet – 8×8 yellow circle
|
||||||
|
g = this.make.graphics({ add: false });
|
||||||
|
g.fillStyle(0xffff00, 1);
|
||||||
|
g.fillCircle(4, 4, 4);
|
||||||
|
g.generateTexture('bullet', 8, 8);
|
||||||
|
g.destroy();
|
||||||
|
|
||||||
|
// Alien bullet – 8×8 red circle
|
||||||
|
g = this.make.graphics({ add: false });
|
||||||
|
g.fillStyle(0xff4444, 1);
|
||||||
|
g.fillCircle(4, 4, 4);
|
||||||
|
g.generateTexture('alien_bullet', 8, 8);
|
||||||
|
g.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
_asteroidPoints(cx, cy, radius, numPoints, offsets) {
|
||||||
|
return offsets.map((scale, i) => {
|
||||||
|
const angle = (i / numPoints) * Math.PI * 2;
|
||||||
|
return {
|
||||||
|
x: cx + Math.cos(angle) * radius * scale,
|
||||||
|
y: cy + Math.sin(angle) * radius * scale
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,8 +11,6 @@ export default class GameScene extends Phaser.Scene {
|
||||||
}
|
}
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
this.createTextures();
|
|
||||||
|
|
||||||
// State
|
// State
|
||||||
this.level = 1;
|
this.level = 1;
|
||||||
this.score = 0;
|
this.score = 0;
|
||||||
|
|
@ -46,88 +44,6 @@ export default class GameScene extends Phaser.Scene {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Texture Generation ───────────────────────────────────────────────────
|
|
||||||
|
|
||||||
createTextures() {
|
|
||||||
// Player ship – texture 64×32, nose points right (angle 0)
|
|
||||||
// Nose: (56,16) left-wing: (12,4) right-wing: (12,28)
|
|
||||||
let g = this.make.graphics({ add: false });
|
|
||||||
g.lineStyle(2, 0x00ff44, 1);
|
|
||||||
g.strokeTriangle(56, 16, 12, 4, 12, 28);
|
|
||||||
g.generateTexture('player', 64, 32);
|
|
||||||
g.destroy();
|
|
||||||
|
|
||||||
// Player ship with thruster flame
|
|
||||||
g = this.make.graphics({ add: false });
|
|
||||||
g.lineStyle(2, 0x00ff44, 1);
|
|
||||||
g.strokeTriangle(56, 16, 12, 4, 12, 28);
|
|
||||||
g.lineStyle(2, 0xff6600, 1);
|
|
||||||
// Flame behind the ship: (12,11),(12,21) -> (0,16)
|
|
||||||
g.strokeTriangle(12, 11, 12, 21, 0, 16);
|
|
||||||
g.generateTexture('player_thrust', 64, 32);
|
|
||||||
g.destroy();
|
|
||||||
|
|
||||||
// Large asteroid – 120×120 texture, radius 50, 12-sided irregular polygon
|
|
||||||
g = this.make.graphics({ add: false });
|
|
||||||
g.lineStyle(2, 0xcccccc, 1);
|
|
||||||
g.strokePoints(this.asteroidPoints(60, 60, 50, 12,
|
|
||||||
[1.0, 0.82, 1.08, 0.88, 1.0, 0.78, 1.1, 0.9, 0.94, 1.0, 0.84, 1.06]
|
|
||||||
), true);
|
|
||||||
g.generateTexture('asteroid_large', 120, 120);
|
|
||||||
g.destroy();
|
|
||||||
|
|
||||||
// Medium asteroid – 64×64, radius 26, 10-sided
|
|
||||||
g = this.make.graphics({ add: false });
|
|
||||||
g.lineStyle(2, 0xcccccc, 1);
|
|
||||||
g.strokePoints(this.asteroidPoints(32, 32, 26, 10,
|
|
||||||
[1.0, 0.78, 1.1, 0.88, 1.0, 0.82, 1.0, 0.92, 1.06, 0.80]
|
|
||||||
), true);
|
|
||||||
g.generateTexture('asteroid_medium', 64, 64);
|
|
||||||
g.destroy();
|
|
||||||
|
|
||||||
// Small asteroid – 32×32, radius 12, 8-sided
|
|
||||||
g = this.make.graphics({ add: false });
|
|
||||||
g.lineStyle(2, 0xcccccc, 1);
|
|
||||||
g.strokePoints(this.asteroidPoints(16, 16, 12, 8,
|
|
||||||
[1.0, 0.78, 1.12, 0.84, 1.0, 0.9, 0.80, 1.04]
|
|
||||||
), true);
|
|
||||||
g.generateTexture('asteroid_small', 32, 32);
|
|
||||||
g.destroy();
|
|
||||||
|
|
||||||
// Alien saucer – 64×48, drawn as two stacked ellipses
|
|
||||||
g = this.make.graphics({ add: false });
|
|
||||||
g.lineStyle(2, 0x00ffff, 1);
|
|
||||||
g.strokeEllipse(32, 30, 52, 20); // main body
|
|
||||||
g.strokeEllipse(32, 22, 30, 18); // dome
|
|
||||||
g.generateTexture('alien', 64, 48);
|
|
||||||
g.destroy();
|
|
||||||
|
|
||||||
// Player bullet – 8×8 yellow circle
|
|
||||||
g = this.make.graphics({ add: false });
|
|
||||||
g.fillStyle(0xffff00, 1);
|
|
||||||
g.fillCircle(4, 4, 4);
|
|
||||||
g.generateTexture('bullet', 8, 8);
|
|
||||||
g.destroy();
|
|
||||||
|
|
||||||
// Alien bullet – 8×8 red circle
|
|
||||||
g = this.make.graphics({ add: false });
|
|
||||||
g.fillStyle(0xff4444, 1);
|
|
||||||
g.fillCircle(4, 4, 4);
|
|
||||||
g.generateTexture('alien_bullet', 8, 8);
|
|
||||||
g.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns array of {x,y} points forming an irregular polygon
|
|
||||||
asteroidPoints(cx, cy, radius, numPoints, offsets) {
|
|
||||||
return offsets.map((scale, i) => {
|
|
||||||
const angle = (i / numPoints) * Math.PI * 2;
|
|
||||||
return {
|
|
||||||
x: cx + Math.cos(angle) * radius * scale,
|
|
||||||
y: cy + Math.sin(angle) * radius * scale
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// ─── Collision Setup ─────────────────────────────────────────────────────
|
// ─── Collision Setup ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
setupCollisions() {
|
setupCollisions() {
|
||||||
|
|
@ -358,8 +274,8 @@ export default class GameScene extends Phaser.Scene {
|
||||||
this.gameOver = true;
|
this.gameOver = true;
|
||||||
this.player.alive = false;
|
this.player.alive = false;
|
||||||
this.player.sprite.setVisible(false);
|
this.player.sprite.setVisible(false);
|
||||||
this.showMessage(`GAME OVER\n\nSCORE: ${this.score}\n\nPress R to restart`);
|
this.showMessage(`GAME OVER\n\nSCORE: ${this.score}\n\nPress R to return to menu`);
|
||||||
this.input.keyboard.once('keydown-R', () => this.scene.restart());
|
this.input.keyboard.once('keydown-R', () => this.scene.start('MenuScene'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Level Completion Check ───────────────────────────────────────────────
|
// ─── Level Completion Check ───────────────────────────────────────────────
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,233 @@
|
||||||
|
import Asteroid from '../entities/Asteroid.js';
|
||||||
|
|
||||||
|
const W = 1600;
|
||||||
|
const H = 900;
|
||||||
|
|
||||||
|
export default class MenuScene extends Phaser.Scene {
|
||||||
|
constructor() {
|
||||||
|
super({ key: 'MenuScene' });
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Lifecycle ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
create() {
|
||||||
|
this.cameras.main.setBackgroundColor('#000011');
|
||||||
|
|
||||||
|
// Background asteroids (no collision needed – just decoration)
|
||||||
|
this.asteroidsGroup = this.physics.add.group();
|
||||||
|
this.asteroids = [];
|
||||||
|
for (let i = 0; i < 9; i++) {
|
||||||
|
this._spawnAsteroid();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wandering alien – plain physics sprite, no collision setup
|
||||||
|
this.alienSprite = this.physics.add.sprite(
|
||||||
|
Phaser.Math.Between(300, 1300),
|
||||||
|
Phaser.Math.Between(300, 600),
|
||||||
|
'alien'
|
||||||
|
);
|
||||||
|
this.alienSprite.body.setAllowGravity(false);
|
||||||
|
this._setAlienVelocity();
|
||||||
|
|
||||||
|
// Periodically change alien direction
|
||||||
|
this.time.addEvent({
|
||||||
|
delay: 2600,
|
||||||
|
callback: this._setAlienVelocity,
|
||||||
|
callbackScope: this,
|
||||||
|
loop: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// UI layers (rendered on top of background entities)
|
||||||
|
this._drawTitle();
|
||||||
|
this._drawControlsPanel();
|
||||||
|
this._drawStartButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
this.asteroids.forEach(a => a.update());
|
||||||
|
if (this.alienSprite && this.alienSprite.active) {
|
||||||
|
this.physics.world.wrap(this.alienSprite, 40);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Background Entities ──────────────────────────────────────────────────
|
||||||
|
|
||||||
|
_spawnAsteroid() {
|
||||||
|
const x = Phaser.Math.Between(40, W - 40);
|
||||||
|
const y = Phaser.Math.Between(40, H - 40);
|
||||||
|
// Weight toward large to fill the screen nicely
|
||||||
|
const roll = Math.random();
|
||||||
|
const size = roll < 0.5 ? 'large' : roll < 0.78 ? 'medium' : 'small';
|
||||||
|
this.asteroids.push(new Asteroid(this, x, y, size, this.asteroidsGroup));
|
||||||
|
}
|
||||||
|
|
||||||
|
_setAlienVelocity() {
|
||||||
|
if (!this.alienSprite || !this.alienSprite.active) return;
|
||||||
|
const angle = Math.random() * Math.PI * 2;
|
||||||
|
const speed = 75 + Math.random() * 65;
|
||||||
|
this.alienSprite.setVelocity(Math.cos(angle) * speed, Math.sin(angle) * speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Title ────────────────────────────────────────────────────────────────
|
||||||
|
//
|
||||||
|
// "3D block letter" look: stack several offset copies of the text in
|
||||||
|
// progressively lighter shades (back → front), finishing with the bright
|
||||||
|
// face on top. Each copy is offset by (i, i) pixels, so the layers
|
||||||
|
// form a visible extrusion going down-right.
|
||||||
|
|
||||||
|
_drawTitle() {
|
||||||
|
const cx = W / 2;
|
||||||
|
const cy = 155;
|
||||||
|
const titleText = 'AIsteroids 2026';
|
||||||
|
|
||||||
|
const style = {
|
||||||
|
fontFamily: '"Courier New", Courier, monospace',
|
||||||
|
fontSize: '98px',
|
||||||
|
fontStyle: 'bold',
|
||||||
|
align: 'center'
|
||||||
|
};
|
||||||
|
|
||||||
|
// Extrusion layers – back (darkest, largest offset) to front
|
||||||
|
const extrusionLayers = [
|
||||||
|
{ offset: 9, color: '#2a0c00' },
|
||||||
|
{ offset: 7, color: '#3e1400' },
|
||||||
|
{ offset: 5, color: '#5c2200' },
|
||||||
|
{ offset: 4, color: '#7a3300' },
|
||||||
|
{ offset: 3, color: '#9a4800' },
|
||||||
|
{ offset: 2, color: '#bb6200' },
|
||||||
|
{ offset: 1, color: '#d97e00' },
|
||||||
|
];
|
||||||
|
|
||||||
|
extrusionLayers.forEach(({ offset, color }) => {
|
||||||
|
this.add.text(cx + offset, cy + offset, titleText, { ...style, color })
|
||||||
|
.setOrigin(0.5)
|
||||||
|
.setDepth(5);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Bright front face
|
||||||
|
const front = this.add.text(cx, cy, titleText, {
|
||||||
|
...style,
|
||||||
|
color: '#ffee44',
|
||||||
|
stroke: '#ffbb00',
|
||||||
|
strokeThickness: 2
|
||||||
|
}).setOrigin(0.5).setDepth(6);
|
||||||
|
|
||||||
|
// Gentle pulse so it feels alive
|
||||||
|
this.tweens.add({
|
||||||
|
targets: front,
|
||||||
|
alpha: { from: 1, to: 0.75 },
|
||||||
|
duration: 1900,
|
||||||
|
ease: 'Sine.InOut',
|
||||||
|
yoyo: true,
|
||||||
|
repeat: -1
|
||||||
|
});
|
||||||
|
|
||||||
|
// Thin decorative lines flanking the title
|
||||||
|
const lineY = cy + 68;
|
||||||
|
const gfx = this.add.graphics().setDepth(5);
|
||||||
|
gfx.lineStyle(1, 0x886622, 0.7);
|
||||||
|
gfx.beginPath();
|
||||||
|
gfx.moveTo(80, lineY); gfx.lineTo(560, lineY);
|
||||||
|
gfx.moveTo(1040, lineY); gfx.lineTo(1520, lineY);
|
||||||
|
gfx.strokePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Controls Panel ───────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
_drawControlsPanel() {
|
||||||
|
const panelX = W / 2;
|
||||||
|
const panelY = 490;
|
||||||
|
const panelW = 820;
|
||||||
|
const panelH = 320;
|
||||||
|
|
||||||
|
// Semi-transparent backing so text is readable over floating asteroids
|
||||||
|
const gfx = this.add.graphics().setDepth(7);
|
||||||
|
gfx.fillStyle(0x000018, 0.82);
|
||||||
|
gfx.fillRoundedRect(panelX - panelW / 2, panelY - panelH / 2, panelW, panelH, 12);
|
||||||
|
gfx.lineStyle(1, 0x224466, 0.9);
|
||||||
|
gfx.strokeRoundedRect(panelX - panelW / 2, panelY - panelH / 2, panelW, panelH, 12);
|
||||||
|
|
||||||
|
// Header
|
||||||
|
this.add.text(panelX, panelY - panelH / 2 + 26, '── HOW TO PLAY ──', {
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#44ddaa',
|
||||||
|
align: 'center'
|
||||||
|
}).setOrigin(0.5, 0).setDepth(8);
|
||||||
|
|
||||||
|
// Control entries
|
||||||
|
const entries = [
|
||||||
|
['Mouse', 'Aim your ship'],
|
||||||
|
['Hold LMB', 'Thrust / Accelerate'],
|
||||||
|
['A or SPACE', 'Fire weapon'],
|
||||||
|
];
|
||||||
|
|
||||||
|
const entryBaseY = panelY - panelH / 2 + 68;
|
||||||
|
const keyStyle = { fontFamily: 'monospace', fontSize: '19px', color: '#ffdd66', align: 'right' };
|
||||||
|
const descStyle = { fontFamily: 'monospace', fontSize: '19px', color: '#aaccff', align: 'left' };
|
||||||
|
|
||||||
|
entries.forEach(([key, desc], i) => {
|
||||||
|
const ey = entryBaseY + i * 36;
|
||||||
|
this.add.text(panelX - 20, ey, key, keyStyle).setOrigin(1, 0).setDepth(8);
|
||||||
|
this.add.text(panelX - 10, ey, '→', { ...descStyle, color: '#556677' }).setOrigin(0, 0).setDepth(8);
|
||||||
|
this.add.text(panelX + 10, ey, desc, descStyle).setOrigin(0, 0).setDepth(8);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Flavour text
|
||||||
|
const noteStyle = { fontFamily: 'monospace', fontSize: '17px', color: '#778899', align: 'center' };
|
||||||
|
this.add.text(panelX, panelY + panelH / 2 - 62,
|
||||||
|
'Destroy all asteroids and alien ships to advance levels.',
|
||||||
|
noteStyle
|
||||||
|
).setOrigin(0.5, 0).setDepth(8);
|
||||||
|
this.add.text(panelX, panelY + panelH / 2 - 36,
|
||||||
|
'Beware — aliens will hunt you and fire back!',
|
||||||
|
{ ...noteStyle, color: '#cc6655' }
|
||||||
|
).setOrigin(0.5, 0).setDepth(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Start Button ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
_drawStartButton() {
|
||||||
|
const cx = W / 2;
|
||||||
|
|
||||||
|
const btn = this.add.text(cx, 790, '[ START GAME ]', {
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
fontSize: '52px',
|
||||||
|
fontStyle: 'bold',
|
||||||
|
color: '#00ff88',
|
||||||
|
stroke: '#007744',
|
||||||
|
strokeThickness: 4
|
||||||
|
}).setOrigin(0.5).setDepth(9).setInteractive({ useHandCursor: true });
|
||||||
|
|
||||||
|
btn.on('pointerover', () => btn.setStyle({ color: '#ffffff', stroke: '#00cc66' }));
|
||||||
|
btn.on('pointerout', () => btn.setStyle({ color: '#00ff88', stroke: '#007744' }));
|
||||||
|
btn.on('pointerdown', () => this._startGame());
|
||||||
|
|
||||||
|
// Also allow Enter key
|
||||||
|
this.input.keyboard.once('keydown-ENTER', () => this._startGame());
|
||||||
|
|
||||||
|
// Slow blink so it draws the eye
|
||||||
|
this.tweens.add({
|
||||||
|
targets: btn,
|
||||||
|
alpha: { from: 1, to: 0.35 },
|
||||||
|
duration: 700,
|
||||||
|
ease: 'Sine.InOut',
|
||||||
|
yoyo: true,
|
||||||
|
repeat: -1
|
||||||
|
});
|
||||||
|
|
||||||
|
this.add.text(cx, 848, 'or press ENTER', {
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
fontSize: '16px',
|
||||||
|
color: '#445566'
|
||||||
|
}).setOrigin(0.5).setDepth(9);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Transition ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
_startGame() {
|
||||||
|
// Phaser shuts down this scene automatically when the next one starts;
|
||||||
|
// all timers, tweens, and physics objects are cleaned up by the engine.
|
||||||
|
this.scene.start('GameScene');
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue