301 lines
10 KiB
JavaScript
301 lines
10 KiB
JavaScript
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);
|
|
}
|
|
} |