More sound effects and video

This commit is contained in:
Brian Fertig 2025-08-24 11:14:21 -06:00
parent fd7e0909e8
commit d4beae5984
5 changed files with 216 additions and 12 deletions

BIN
assets/alarm.mp3 Normal file

Binary file not shown.

BIN
assets/countdown.mp3 Normal file

Binary file not shown.

BIN
assets/game-over-boom.mp3 Normal file

Binary file not shown.

Binary file not shown.

View File

@ -15,11 +15,12 @@ export class GameScene extends Phaser.Scene {
// Stats // Stats
this.numberOfJewels = 4; this.numberOfJewels = 4;
this.startRows = 3; this.startRows = 5;
this.level = 1; this.level = 1;
this.matchesNeeded = 8; this.matchesNeeded = 8;
this.score = 0; this.score = 0;
this.ally = 'goblin'; this.ally = 'goblin';
this.gameStatus = true;
// Status Indication // Status Indication
this.isDropping = false; this.isDropping = false;
@ -37,6 +38,7 @@ export class GameScene extends Phaser.Scene {
this.moveTimer = 0; this.moveTimer = 0;
this.moveInterval = 12000; this.moveInterval = 12000;
this.timerText = null; this.timerText = null;
this.countdownTimer = false;
} }
preload() { preload() {
@ -56,6 +58,9 @@ export class GameScene extends Phaser.Scene {
this.load.audio('clear', 'assets/clear.mp3'); this.load.audio('clear', 'assets/clear.mp3');
this.load.audio('level-up', 'assets/level-up.mp3'); this.load.audio('level-up', 'assets/level-up.mp3');
this.load.audio('switch', 'assets/switch.mp3'); this.load.audio('switch', 'assets/switch.mp3');
this.load.audio('game-over', 'assets/game-over-boom.mp3');
this.load.audio('countdown', 'assets/countdown.mp3');
this.load.audio('alarm', 'assets/alarm.mp3');
// Ally Assets // Ally Assets
const allys = ['goblin']; const allys = ['goblin'];
@ -64,6 +69,7 @@ export class GameScene extends Phaser.Scene {
this.load.video(`${ally}-excited`, 'assets/goblin-excited.mp4'); this.load.video(`${ally}-excited`, 'assets/goblin-excited.mp4');
this.load.video(`${ally}-pleased`, 'assets/goblin-pleased.mp4'); this.load.video(`${ally}-pleased`, 'assets/goblin-pleased.mp4');
this.load.video(`${ally}-match`, 'assets/goblin-match.mp4'); this.load.video(`${ally}-match`, 'assets/goblin-match.mp4');
this.load.video(`${ally}-background`, `assets/${ally}-background.mp4`);
this.load.audio(`${ally}-a1`, 'assets/goblin-a1.mp3'); this.load.audio(`${ally}-a1`, 'assets/goblin-a1.mp3');
this.load.audio(`${ally}-a2`, 'assets/goblin-a2.mp3'); this.load.audio(`${ally}-a2`, 'assets/goblin-a2.mp3');
this.load.audio(`${ally}-a3`, 'assets/goblin-a3.mp3'); this.load.audio(`${ally}-a3`, 'assets/goblin-a3.mp3');
@ -75,6 +81,16 @@ export class GameScene extends Phaser.Scene {
} }
create() { create() {
// Background Video
this.bgVideo = this.add.video(0, 0, `${this.ally}-background`);
this.bgVideo.setOrigin(0);
console.log("width",this.scale.width);
this.bgVideo.scaleX = this.scale.width / 848;
this.bgVideo.scaleY = this.scale.height / 480;
console.log(this.bgVideo);
this.bgVideo.play(true);
// Create the Game Grid
this.makeGrid(); this.makeGrid();
this.physics.world.setBounds(this.grid.getBounds().x - 50, this.grid.getBounds().y - 50, this.grid.getBounds().width + 100, this.grid.getBounds().height + 100); this.physics.world.setBounds(this.grid.getBounds().x - 50, this.grid.getBounds().y - 50, this.grid.getBounds().width + 100, this.grid.getBounds().height + 100);
this.jewels = this.physics.add.group({ this.jewels = this.physics.add.group({
@ -88,6 +104,17 @@ export class GameScene extends Phaser.Scene {
this.bgMusic.loop = true; this.bgMusic.loop = true;
this.bgMusic.play(); this.bgMusic.play();
// Create Ally Video
this.allyVideo = this.add.video(350, 610, `${this.ally}-resting`).setOrigin(0.5);
this.allyVideo.play(true);
this.allyVideo.postFX.addGlow();
this.time.delayedCall(500, () => {
this.sound.play(`${this.ally}-intro`);
});
// Create Text Background
this.add.rectangle(10, 40, 650, 270, 0x000000, .5).setOrigin(0);
// Create the score text // Create the score text
this.scoreText = this.add.text(20, 50, 'Score: 0', { this.scoreText = this.add.text(20, 50, 'Score: 0', {
fontFamily: 'cruiser, arial', fontFamily: 'cruiser, arial',
@ -139,12 +166,6 @@ export class GameScene extends Phaser.Scene {
bottom: 5 bottom: 5
} }
}).setOrigin(0); }).setOrigin(0);
this.allyVideo = this.add.video(350, 610, `${this.ally}-resting`).setOrigin(0.5);
this.allyVideo.play(true);
this.time.delayedCall(500, () => {
this.sound.play(`${this.ally}-intro`);
});
} }
update(time, delta) { update(time, delta) {
@ -152,11 +173,21 @@ export class GameScene extends Phaser.Scene {
this.moveTimer += delta; this.moveTimer += delta;
// Check if it's time to move all jewels up // Check if it's time to move all jewels up
if (this.moveTimer >= this.moveInterval && this.isDropping === false && this.isSwapping === false && this.isDestroying === false) { if (
this.moveTimer >= this.moveInterval &&
this.isDropping === false &&
this.isSwapping === false &&
this.isDestroying === false &&
this.gameStatus === true
) {
this.moveAllJewelsUp(); this.moveAllJewelsUp();
this.moveTimer = 0; // Reset the timer this.moveTimer = 0; // Reset the timer
} }
if (this.moveInterval - this.moveTimer <= 3000) {
this.startCountdownTimer();
}
// Update the timer display // Update the timer display
const timeRemaining = (this.moveInterval - this.moveTimer) / 1000; const timeRemaining = (this.moveInterval - this.moveTimer) / 1000;
const displayTime = timeRemaining.toFixed(2); const displayTime = timeRemaining.toFixed(2);
@ -165,6 +196,18 @@ export class GameScene extends Phaser.Scene {
} }
} }
startCountdownTimer() {
if (this.countdownTimer === true || this.gameStatus === false) {
return;
}
this.countdownTimer = true;
this.sound.play('countdown');
this.time.delayedCall(6000, () => {
this.countdownTimer = false;
});
}
makeGrid() { makeGrid() {
this.grid = this.add.rectangle( this.grid = this.add.rectangle(
this.gridConfig.leftPadding + this.gridConfig.allPadding, this.gridConfig.leftPadding + this.gridConfig.allPadding,
@ -174,6 +217,10 @@ export class GameScene extends Phaser.Scene {
0x000000, 0x000000,
.5 .5
).setOrigin(0); ).setOrigin(0);
this.grid.setInteractive();
this.grid.on('pointerdown', (pointer) => {
this.handleGridClick(pointer.x, pointer.y);
});
} }
createJewel(type, col, row) { createJewel(type, col, row) {
@ -251,11 +298,97 @@ export class GameScene extends Phaser.Scene {
return jewelAtPosition ? jewelAtPosition.jewelType : null; return jewelAtPosition ? jewelAtPosition.jewelType : null;
} }
// Handle clicks on the grid
handleGridClick(x, y) {
if (!this.selectedJewel) {
return;
}
const selectedX = this.selectedJewel.x;
const selectedY = this.selectedJewel.y;
// Calculate which grid tile was clicked
const clickCol = Math.floor((x+50) / this.gridConfig.jewelWidth);
const clickRow = Math.floor((y+50) / this.gridConfig.jewelHeight);
// Calculate selected jewel's grid position
const selectedCol = Math.floor(selectedX / this.gridConfig.jewelWidth);
const selectedRow = Math.floor(selectedY / this.gridConfig.jewelHeight);
// Check if click is adjacent (up, down, left, right)
const isAdjacent =
(clickCol === selectedCol && Math.abs(clickRow - selectedRow) === 1) || // Up or down
(clickRow === selectedRow && Math.abs(clickCol - selectedCol) === 1); // Left or right
if (isAdjacent) {
this.tweens.add({
targets: this.selectedJewel,
scale: 1,
duration: 200
});
this.moveJewel(clickCol * this.gridConfig.jewelWidth, clickRow * this.gridConfig.jewelHeight);
}
}
// Modified swap function to disable clicks during execution
moveJewel(x ,y) {
if (this.isMovingUp === true) {
this.time.delayedCall(1000, ()=> {
this.moveJewel(x, y);
})
return;
}
// Set swapping flag to prevent new clicks from being processed
this.isSwapping = true;
this.sound.play('switch');
// Disable all jewel interactivity temporarily
this.jewels.children.iterate((jewel) => {
if (jewel) {
jewel.disableInteractive();
}
});
// Perform the swap animation here - currently empty
const fromX = this.selectedJewel.x;
const fromY = this.selectedJewel.y;
const toX = x;
const toY = y;
this.tweens.add({
targets: this.selectedJewel,
x: toX,
y: toY,
duration: 300,
onComplete: () => {
this.dropJewels();
this.time.delayedCall(300, () => {
this.checkMatches();
})
}
});
this.selectedJewel = null;
this.swapWithJewel = null;
// After swap completes, re-enable interactivity and reset flag
this.time.delayedCall(300, () => { // Adjust delay as needed for animation duration
this.jewels.children.iterate((jewel) => {
if (jewel) {
jewel.setInteractive();
}
});
this.isSwapping = false;
});
}
// New function to handle jewel clicks // New function to handle jewel clicks
handleJewelClick(x, y) { handleJewelClick(x, y) {
// Find which jewel was clicked // Find which jewel was clicked
const clickedJewel = this.getJewelAtWorldPosition(x, y); const clickedJewel = this.getJewelAtWorldPosition(x, y);
//const isAdjacentButEmpty = this.isAdjacentButEmtpy(this.selectedJewel, x, y);
if (!clickedJewel || this.isSwapping) { if (!clickedJewel || this.isSwapping) {
return; return;
} }
@ -351,7 +484,7 @@ export class GameScene extends Phaser.Scene {
// Modified swap function to disable clicks during execution // Modified swap function to disable clicks during execution
swapJewel() { swapJewel() {
if (this.isMovingUp === true) { if (this.isMovingUp === true) {
this.time.delayedCall(300, ()=> { this.time.delayedCall(500, ()=> {
this.swapJewel(); this.swapJewel();
}) })
return; return;
@ -876,9 +1009,80 @@ export class GameScene extends Phaser.Scene {
// Game over function // Game over function
gameOver() { gameOver() {
console.log('Game Over!'); console.log('Game Over!');
// Add game over logic here (e.g., show game over screen, reset game, etc.) this.gameStatus = false;
this.sound.play('game-over');
// For now, just restart the scene // Make all jewels bounce off screen
this.scene.restart(); 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);
}
});
// Create the New Level text
const gameOverText = this.add.text(1150, 250, `Game Over`, {
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.scene.restart();
}
});
});
}
});
});
} }
} }