Two Levels and polish

This commit is contained in:
Brian Fertig 2025-08-29 21:26:42 -06:00
parent ca135fd1c7
commit db61bbfbf3
58 changed files with 326 additions and 16 deletions

BIN
android-chrome-192x192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
android-chrome-512x512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

BIN
apple-touch-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 348 KiB

After

Width:  |  Height:  |  Size: 715 KiB

Binary file not shown.

Binary file not shown.

BIN
assets/menuFrame.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 KiB

Binary file not shown.

BIN
assets/shark-a1.mp3 Normal file

Binary file not shown.

BIN
assets/shark-a2.mp3 Normal file

Binary file not shown.

BIN
assets/shark-a3.mp3 Normal file

Binary file not shown.

BIN
assets/shark-b.mp3 Normal file

Binary file not shown.

BIN
assets/shark-background.mp4 Normal file

Binary file not shown.

BIN
assets/shark-c.mp3 Normal file

Binary file not shown.

BIN
assets/shark-excited.mp4 Normal file

Binary file not shown.

BIN
assets/shark-intro.mp3 Normal file

Binary file not shown.

BIN
assets/shark-match.mp4 Normal file

Binary file not shown.

BIN
assets/shark-music.mp3 Normal file

Binary file not shown.

BIN
assets/shark-outro.mp3 Normal file

Binary file not shown.

BIN
assets/shark-pleased.mp4 Normal file

Binary file not shown.

BIN
assets/shark-resting.mp4 Normal file

Binary file not shown.

BIN
assets/shark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

BIN
assets/steam-a1.mp3 Normal file

Binary file not shown.

BIN
assets/steam-a2.mp3 Normal file

Binary file not shown.

BIN
assets/steam-a3.mp3 Normal file

Binary file not shown.

BIN
assets/steam-b.mp3 Normal file

Binary file not shown.

BIN
assets/steam-background.mp4 Normal file

Binary file not shown.

BIN
assets/steam-c.mp3 Normal file

Binary file not shown.

BIN
assets/steam-excited.mp4 Normal file

Binary file not shown.

BIN
assets/steam-intro.mp3 Normal file

Binary file not shown.

BIN
assets/steam-match.mp4 Normal file

Binary file not shown.

BIN
assets/steam-music.mp3 Normal file

Binary file not shown.

BIN
assets/steam-outro.mp3 Normal file

Binary file not shown.

BIN
assets/steam-pleased.mp4 Normal file

Binary file not shown.

BIN
assets/steam-resting.mp4 Normal file

Binary file not shown.

BIN
assets/steam.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

BIN
favicon-16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 937 B

BIN
favicon-32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -3,6 +3,16 @@ import { LEVEL_CONFIG } from './config.js';
export class GameScene extends Phaser.Scene {
constructor() {
super({ key: 'GameScene' });
}
init(data) {
this.level = 1;
// Receive data passed from MenuScene
if (data && data.level !== undefined) {
this.level = data.level;
console.log('Current level received:', this.currentLevel);
}
this.gridConfig = {
allPadding: 50,
@ -16,7 +26,6 @@ export class GameScene extends Phaser.Scene {
// Stats
this.numberOfJewels = 4;
this.startRows = 5;
this.level = 1;
this.matchesNeeded = 8;
this.score = 0;
this.ally = 'goblin';
@ -65,7 +74,7 @@ export class GameScene extends Phaser.Scene {
this.load.audio('alarm', 'assets/alarm.mp3');
// Ally Assets
const allys = ['goblin', 'surfer', 'bear', 'wizard'];
const allys = ['goblin', 'surfer', 'bear', 'wizard', 'steam', 'shark'];
allys.forEach((ally) => {
this.load.video(`${ally}-resting`, `assets/${ally}-resting.mp4`);
this.load.video(`${ally}-excited`, `assets/${ally}-excited.mp4`);
@ -344,7 +353,7 @@ export class GameScene extends Phaser.Scene {
// Modified swap function to disable clicks during execution
moveJewel(x ,y) {
if (this.isMovingUp === true) {
this.time.delayedCall(1000, ()=> {
this.time.delayedCall(1200, ()=> {
this.moveJewel(x, y);
})
return;
@ -536,7 +545,7 @@ export class GameScene extends Phaser.Scene {
// After swap completes, re-enable interactivity and reset flag
this.time.delayedCall(300, () => { // Adjust delay as needed for animation duration
this.time.delayedCall(400, () => { // Adjust delay as needed for animation duration
this.jewels.children.iterate((jewel) => {
if (jewel) {
jewel.setInteractive();
@ -874,7 +883,7 @@ export class GameScene extends Phaser.Scene {
});
// Create new bottom row after moving all jewels up
this.time.delayedCall(300, () => {
this.time.delayedCall(500, () => {
this.isMovingUp = false;
this.createBottomRow();
this.checkWarning();
@ -1065,6 +1074,11 @@ export class GameScene extends Phaser.Scene {
levelUp() {
this.level ++;
if (this.level === 25) {
this.gameStatus === false
this.gameEnd();
return;
}
const newLevel = LEVEL_CONFIG[this.level];
this.numberOfJewels = newLevel.numberOfJewels;
this.matchesNeeded = newLevel.matchesNeeded;
@ -1148,7 +1162,6 @@ export class GameScene extends Phaser.Scene {
// Game over function
gameOver() {
console.log('Game Over!');
this.gameStatus = false;
this.sound.play('game-over');
this.rowOne = false;
@ -1231,4 +1244,113 @@ export class GameScene extends Phaser.Scene {
});
});
}
// Game over function
gameEnd() {
this.gameStatus = false;
this.sound.play('game-over');
this.rowOne = false;
this.grid.setFillStyle(this.gridColor).setAlpha(0.5);
// Make all jewels bounce off screen
this.jewels.children.iterate((jewel) => {
if (jewel) {
// Enable physics for the jewel if not already enabled
if (!jewel.body) {
this.physics.add.existing(jewel);
}
// Remove world bounds collision
jewel.body.setCollideWorldBounds(false);
// Set random velocity for bouncing effect
const angle = Phaser.Math.Between(0, 360);
const speed = Phaser.Math.Between(100, 300);
jewel.body.setVelocity(
Math.cos(angle) * speed,
Math.sin(angle) * speed
);
// Add some rotation for visual effect
jewel.body.angularVelocity = Phaser.Math.Between(-200, 200);
// Get some points!
const delay = Phaser.Math.Between(100,6000);
this.time.delayedCall(delay, () => {
this.score += 100;
this.scoreText.setText(`Score: ${this.score}`);
this.sound.play('clear');
this.tweens.add({
targets: jewel,
scaleX: 0,
scaleY: 0,
alpha: 0,
duration: 200,
onComplete: () => {
jewel.destroy();
}
});
});
}
});
if (this.alarm) {
this.alarm.stop();
}
if (this.alarmFlash) {
this.alarmFlash.remove();
this.alarmFlash = null;
}
// Create the New Level text
const gameOverText = this.add.text(1150, 250, `YOU WIN!!!`, {
fontFamily: 'code, arial',
fontSize: '100px',
fill: '#ea00ffff',
padding: {
left: 10,
right: 10,
top: 5,
bottom: 5
}
}).setOrigin(0.5);
// Add cool eye-catching effect
this.tweens.add({
targets: gameOverText,
scale: { from: 0.5, to: 1.5 },
alpha: { from: 0, to: 1 },
duration: 1000,
ease: 'Back.easeOut',
});
// Fade out and destroy after 2000ms
this.time.delayedCall(10200, () => {
this.tweens.add({
targets: gameOverText,
angle: 360,
scale: 0,
alpha: 0,
duration: 500,
onComplete: () => {
gameOverText.destroy();
this.time.delayedCall(3000, () => {
// Fade out camera
this.tweens.add({
targets: this.cameras.main,
opacity: 0,
duration: 1500,
ease: 'Linear',
onComplete: () => {
this.sound.stopAll();
this.scene.start('MenuScene');
}
});
});
}
});
});
}
}

View File

@ -2,6 +2,49 @@ 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() {
@ -13,8 +56,12 @@ export class MenuScene extends Phaser.Scene {
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() {
@ -69,7 +116,9 @@ export class MenuScene extends Phaser.Scene {
this.bgMusic.destroy();
// Start the game scene
this.scene.start('GameScene');
this.scene.start('GameScene', {
level: this.currentLevel
});
}
});
});
@ -89,6 +138,63 @@ export class MenuScene extends Phaser.Scene {
}
}).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);
@ -101,7 +207,7 @@ export class MenuScene extends Phaser.Scene {
scale: .9,
duration: 4000,
ease: 'Back.out',
delay: 500,
delay: 1000,
onComplete: () => {
// Pulse Menu
this.tweens.add({
@ -121,12 +227,27 @@ export class MenuScene extends Phaser.Scene {
ease: 'Quart.out',
onComplete: () => {
this.tweens.add({
targets: this.startMenuText,
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'
});
}
});
}
@ -156,7 +277,10 @@ export class MenuScene extends Phaser.Scene {
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(0, 4);
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);

View File

@ -97,19 +97,19 @@ export const LEVEL_CONFIG = {
},
13: {
numberOfJewels: 7,
matchesNeeded: 8,
matchesNeeded: 6,
moveInterval: 8000,
ally: 'wizard',
spritePlus: 18,
gridColor: 0xFFFFFF
gridColor: 0xffef6a
},
14: {
numberOfJewels: 8,
matchesNeeded: 8,
matchesNeeded: 7,
moveInterval: 9000,
ally: 'wizard',
spritePlus: 18,
gridColor: 0xFFFFFF
gridColor: 0xffc000
},
15: {
numberOfJewels: 9,
@ -117,7 +117,7 @@ export const LEVEL_CONFIG = {
moveInterval: 10000,
ally: 'wizard',
spritePlus: 18,
gridColor: 0xFFFFFF
gridColor: 0xff9000
},
16: {
numberOfJewels: 10,
@ -125,6 +125,70 @@ export const LEVEL_CONFIG = {
moveInterval: 11000,
ally: 'wizard',
spritePlus: 18,
gridColor: 0xFFFFFF
gridColor: 0x583200
},
17: {
numberOfJewels: 10,
matchesNeeded: 8,
moveInterval: 11000,
ally: 'steam',
spritePlus: 28,
gridColor: 0x8c4c00
},
18: {
numberOfJewels: 11,
matchesNeeded: 8,
moveInterval: 11000,
ally: 'steam',
spritePlus: 28,
gridColor: 0xffb24e
},
19: {
numberOfJewels: 12,
matchesNeeded: 8,
moveInterval: 11500,
ally: 'steam',
spritePlus: 28,
gridColor: 0x4ef9ff
},
20: {
numberOfJewels: 12,
matchesNeeded: 8,
moveInterval: 11000,
ally: 'steam',
spritePlus: 28,
gridColor: 0x00999f
},
21: {
numberOfJewels: 12,
matchesNeeded: 8,
moveInterval: 11000,
ally: 'shark',
spritePlus: 40,
gridColor: 0x83ffbd
},
22: {
numberOfJewels: 13,
matchesNeeded: 8,
moveInterval: 11500,
ally: 'shark',
spritePlus: 40,
gridColor: 0x83fff8
},
23: {
numberOfJewels: 14,
matchesNeeded: 8,
moveInterval: 12000,
ally: 'shark',
spritePlus: 40,
gridColor: 0x00ffba
},
24: {
numberOfJewels: 15,
matchesNeeded: 8,
moveInterval: 11500,
ally: 'shark',
spritePlus: 40,
gridColor: 0x00fff0
}
};