More sound effects and video
This commit is contained in:
parent
fd7e0909e8
commit
d4beae5984
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
228
src/GameScene.js
228
src/GameScene.js
|
|
@ -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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue