Asteroids-2026/js/scenes/BootScene.js

179 lines
7.2 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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' });
}
preload() {
this.load.audio('title', 'js/audio/music/title.mp3');
this.load.audio('track01', 'js/audio/music/track01.mp3');
this.load.audio('track02', 'js/audio/music/track02.mp3');
this.load.audio('track03', 'js/audio/music/track03.mp3');
this.load.audio('track04', 'js/audio/music/track04.mp3');
this.load.audio('track05', 'js/audio/music/track05.mp3');
this.load.audio('track06', 'js/audio/music/track06.mp3');
this.load.audio('track07', 'js/audio/music/track07.mp3');
this.load.audio('sfx_player_shoot', 'js/audio/fx/player_shoot.mp3');
this.load.audio('sfx_player_death', 'js/audio/fx/player_death.mp3');
this.load.audio('sfx_alien_shoot', 'js/audio/fx/alien_shoot.mp3');
this.load.audio('sfx_missle', 'js/audio/fx/missle.mp3');
this.load.audio('sfx_impact', 'js/audio/fx/impact.mp3');
this.load.audio('sfx_alien_death', 'js/audio/fx/alien_death.mp3');
this.load.audio('sfx_thruster', 'js/audio/fx/thruster.mp3');
}
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();
// Spread-shot alien 72×54, orange/red menacing saucer
g = this.make.graphics({ add: false });
g.lineStyle(2, 0xff4400, 1);
g.strokeEllipse(36, 34, 62, 18); // wide flat hull
g.strokeEllipse(36, 24, 38, 22); // taller upper dome
g.fillStyle(0xff8800, 1);
g.fillCircle(36, 26, 5); // central cannon port
g.lineStyle(2, 0xff2200, 1);
g.beginPath(); g.moveTo(5, 34); g.lineTo(0, 27); g.strokePath(); // left spike
g.beginPath(); g.moveTo(67, 34); g.lineTo(72, 27); g.strokePath(); // right spike
g.generateTexture('alien_spread', 72, 54);
g.destroy();
// Homing-missile alien 80×60, purple/magenta angular diamond
g = this.make.graphics({ add: false });
g.lineStyle(2, 0xcc00ff, 1);
g.strokePoints([
{ x: 40, y: 5 },
{ x: 72, y: 30 },
{ x: 40, y: 55 },
{ x: 8, y: 30 }
], true);
g.lineStyle(1, 0x9900cc, 1);
g.strokePoints([
{ x: 40, y: 18 },
{ x: 58, y: 30 },
{ x: 40, y: 42 },
{ x: 22, y: 30 }
], true);
g.fillStyle(0xff00ff, 1);
g.fillCircle(40, 30, 5);
g.generateTexture('alien_missile', 80, 60);
g.destroy();
// Homing missile projectile 14×6, magenta body + orange nose
g = this.make.graphics({ add: false });
g.fillStyle(0xff00ff, 1);
g.fillRect(0, 1, 10, 4);
g.fillStyle(0xff8800, 1);
g.fillRect(10, 0, 4, 6);
g.generateTexture('homing_missile', 14, 6);
g.destroy();
// Reticle outer layer outer ring + diagonal ticks (rotates one way)
g = this.make.graphics({ add: false });
g.lineStyle(1.5, 0x00ff44, 1);
g.strokeCircle(32, 32, 28);
g.lineStyle(1, 0x00ff44, 0.5);
g.beginPath(); g.moveTo(12, 12); g.lineTo(18, 18); g.strokePath();
g.beginPath(); g.moveTo(52, 12); g.lineTo(46, 18); g.strokePath();
g.beginPath(); g.moveTo(12, 52); g.lineTo(18, 46); g.strokePath();
g.beginPath(); g.moveTo(52, 52); g.lineTo(46, 46); g.strokePath();
g.generateTexture('reticle_outer', 64, 64);
g.destroy();
// Reticle inner layer inner ring + cross lines (rotates opposite way)
g = this.make.graphics({ add: false });
g.lineStyle(1.5, 0x00ff44, 1);
g.strokeCircle(32, 32, 6);
g.beginPath(); g.moveTo(32, 2); g.lineTo(32, 24); g.strokePath(); // top
g.beginPath(); g.moveTo(32, 40); g.lineTo(32, 62); g.strokePath(); // bottom
g.beginPath(); g.moveTo( 2, 32); g.lineTo(24, 32); g.strokePath(); // left
g.beginPath(); g.moveTo(40, 32); g.lineTo(62, 32); g.strokePath(); // right
g.generateTexture('reticle_inner', 64, 64);
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
};
});
}
}