export class MenuScene extends Phaser.Scene { constructor() { super({ key: 'MenuScene' }); this.allies = { 'goblin': { 'level': 1, 'spriteFrom': 0, 'spriteTo': 4 }, 'surfer': { 'level': 5, 'spriteFrom': 5, 'spriteTo': 10 }, 'bear': { 'level': 9, 'spriteFrom': 11, 'spriteTo': 17 }, 'wizard': { 'level': 13, 'spriteFrom': 18, 'spriteTo': 27 }, 'steam': { 'level': 17, 'spriteFrom': 28, 'spriteTo': 39 }, 'shark': { 'level': 21, 'spriteFrom': 40, 'spriteTo': 54 }, }; this.allyNames = []; for (let ally in this.allies) { this.allyNames.push(ally); } } init(data) { this.currentAlly = 0; this.currentLevel = 1; this.currentDifficulty = 'Easy'; } preload() { this.load.spritesheet('jewels', 'assets/jewels.png', { frameWidth: 100, frameHeight: 100 }); this.load.image('menuBackground', 'assets/menuBackground.png'); this.load.image('menuLogo', 'assets/menuLogo.png'); this.load.image('menuPlate', 'assets/menuPlate.png'); this.load.image('menuFrame', 'assets/menuFrame.png'); this.load.audio('menuMusic', 'assets/menuMusic.mp3'); this.load.font('royalAcid', 'assets/Royalacid.ttf'); for (let ally in this.allies) { this.load.image(`${ally}-pic`, `assets/${ally}.png`); } } create() { // Set background image to full screen size const background = this.add.image(0, 0, 'menuBackground'); background.setOrigin(0, 0); background.setScale( this.game.config.width / background.width, this.game.config.height / background.height ); // Theme Music this.bgMusic = this.sound.add('menuMusic'); this.bgMusic.loop = true; this.bgMusic.play(); // Create array to store jewel objects this.jewels = []; // Set up timer for spawning jewels this.spawnTimer = this.time.addEvent({ delay: Phaser.Math.Between(500, 2000), callback: this.spawnJewel, callbackScope: this, loop: true }); // Setup Menu this.startMenu = this.add.image(300, 650, 'menuPlate').setOrigin(0.5).setScale(0); this.startMenu.preFX.addShadow(-5, -5, .005); // Make the start menu clickable this.startMenu.setInteractive(); this.startMenu.on('pointerdown', () => { // Create fade overlay const fadeOverlay = this.add.rectangle( 0, 0, this.game.config.width, this.game.config.height, 0x000000 ); fadeOverlay.setOrigin(0, 0); // Fade out overlay and transition to GameScene this.tweens.add({ targets: fadeOverlay, alpha: 1, duration: 1000, onComplete: () => { // Stop and destroy the music after fadeout this.bgMusic.stop(); this.bgMusic.destroy(); // Start the game scene this.scene.start('GameScene', { level: this.currentLevel }); } }); }); this.startMenuText = this.add.text(180, 630, 'New Game', { fontFamily: 'royalAcid, arial', fontSize: '56px', fill: '#f375ed', // Primary color for the text stroke: '#40faf6', // Secondary color for stroke (creates gradient effect) strokeThickness: 2, shadow: { offsetX: 3, offsetY: 3, color: '#1b426e', blur: 5, fill: true } }).setAlpha(0); // Setup Ally Selector this.allyImage = this.add.image(1350, 550, `${this.allyNames[this.currentAlly]}-pic`).setScale(0.17).setAlpha(0); this.allyMenu = this.add.image(1350, 550, 'menuFrame').setOrigin(0.5).setScale(0); this.allyMenu.preFX.addShadow(-5, -5, .005); this.allyMenuBG = this.add.rectangle(1075, 750, 550, 150, 0xf9eec7, .6).setOrigin(0,0).setAlpha(0); this.allyMenuText = this.add.text(1100, 775, 'Starting Ally: Level 1', { fontFamily: 'royalAcid, arial', fontSize: '48px', fill: '#40faf6', // Primary color for the text stroke: '#00b43cff', // Secondary color for stroke (creates gradient effect) strokeThickness: 2, shadow: { offsetX: 3, offsetY: 3, color: '#1b426e', blur: 5, fill: true } }).setAlpha(0).setOrigin(0,0); this.allyMenuDifficulty = this.add.text(1100, 825, 'Easy', { fontFamily: 'royalAcid, arial', fontSize: '48px', fill: '#40faf6', // Primary color for the text stroke: '#00b43cff', // Secondary color for stroke (creates gradient effect) strokeThickness: 2, shadow: { offsetX: 3, offsetY: 3, color: '#1b426e', blur: 5, fill: true } }).setAlpha(0).setOrigin(0,0); this.allyMenu.setInteractive(); this.allyMenu.on('pointerdown', () => { this.currentAlly++; if (this.currentAlly > this.allyNames.length-1) { this.currentAlly = 0; } this.currentLevel = this.allies[this.allyNames[this.currentAlly]].level; if (this.currentLevel < 9) { this.currentDifficulty = 'Easy'; } else if (this.currentLevel < 17) { this.currentDifficulty = 'Medium'; } else if (this.currentLevel < 25) { this.currentDifficulty = 'Hard'; } this.allyImage.setTexture(`${this.allyNames[this.currentAlly]}-pic`); this.allyMenuText.setText('Starting Ally: Level ' + this.currentLevel); this.allyMenuDifficulty.setText(`${this.currentDifficulty}`); }); // Create and animate menu logo this.menuLogo = this.add.image(-300, -300, 'menuLogo'); this.menuLogo.setOrigin(0.5, 0.5); // Animate logo flying in from top left corner this.tweens.add({ targets: this.menuLogo, x: this.game.config.width / 2, y: 350, scale: .9, duration: 4000, ease: 'Back.out', delay: 1000, onComplete: () => { // Pulse Menu this.tweens.add({ targets: this.menuLogo, scale: .8, duration: 2000, yoyo: true, repeat: -1 }); // Start Button this.tweens.add({ targets: this.startMenu, angle: 1080, duration: 1000, scale: 1, ease: 'Quart.out', onComplete: () => { this.tweens.add({ targets: [ this.startMenuText, this.allyMenuText, this.allyMenuDifficulty, this.allyImage, this.allyMenuBG ], duration: 1000, alpha: 1 }); } }); // Start Button this.tweens.add({ targets: this.allyMenu, angle: -1080, duration: 1000, scale: 0.7, ease: 'Quart.out' }); } }); } update(time, delta) { // Update jewel positions this.jewels.forEach((jewel, index) => { if (jewel.active) { // Apply gravity effect (move upward then downward) jewel.y += jewel.velocityY; jewel.velocityY += 0.5; // Gravity effect jewel.x += jewel.velocityX; // Rotate the jewel jewel.rotation += jewel.rotationSpeed; // Remove jewels that go off screen if (jewel.y > this.game.config.height + 100) { jewel.active = false; jewel.setVisible(false); this.jewels.splice(index, 1); } } }); } spawnJewel() { // Create a new jewel at random position at bottom of screen const x = Phaser.Math.Between(50, this.game.config.width - 50); const frame = Phaser.Math.Between( this.allies[this.allyNames[this.currentAlly]].spriteFrom, this.allies[this.allyNames[this.currentAlly]].spriteTo ); // Create jewel sprite const jewel = this.add.sprite(x, this.game.config.height + 50, 'jewels', frame); jewel.setScale(0.8); // Make them slightly smaller // Set initial velocity (moving upward) jewel.velocityY = -25; // Initial upward speed jewel.velocityX = Phaser.Math.Between(-2, 2); jewel.rotationSpeed = Phaser.Math.FloatBetween(-0.1, 0.1); // Random rotation speed jewel.active = true; // Add to jewels array this.jewels.push(jewel); // Set next spawn timer this.spawnTimer.delay = Phaser.Math.Between(500, 2000); } }