From a13a6428e6511f7712eb31ac6055a3f4009350ff Mon Sep 17 00:00:00 2001 From: Son Nguyen Date: Sat, 18 Jan 2025 22:18:07 -0500 Subject: [PATCH] Final: Enhance app functionalities (#196) --- MovieVerse-Frontend/js/dinosaur-jump.js | 6 +-- MovieVerse-Frontend/js/highscores.js | 50 +++++++++++++++++-- MovieVerse-Mobile/app/js/dinosaur-jump.js | 6 +-- MovieVerse-Mobile/app/js/highscores.js | 50 +++++++++++++++++-- .../MovieVerse-Frontend/js/dinosaur-jump.js | 6 +-- .../www/MovieVerse-Frontend/js/highscores.js | 50 +++++++++++++++++-- .../MovieVerse-Frontend/js/dinosaur-jump.js | 6 +-- .../www/MovieVerse-Frontend/js/highscores.js | 50 +++++++++++++++++-- .../MovieVerse-Frontend/js/dinosaur-jump.js | 6 +-- .../www/MovieVerse-Frontend/js/highscores.js | 50 +++++++++++++++++-- MovieVerse-Mobile/www/js/dinosaur-jump.js | 6 +-- MovieVerse-Mobile/www/js/highscores.js | 50 +++++++++++++++++-- 12 files changed, 300 insertions(+), 36 deletions(-) diff --git a/MovieVerse-Frontend/js/dinosaur-jump.js b/MovieVerse-Frontend/js/dinosaur-jump.js index d626fa8d..22eacab5 100644 --- a/MovieVerse-Frontend/js/dinosaur-jump.js +++ b/MovieVerse-Frontend/js/dinosaur-jump.js @@ -134,21 +134,21 @@ function draw() { // Score ctx.fillStyle = 'white'; - ctx.font = "16px 'Poppins', sans-serif"; + ctx.font = "10px 'Poppins', sans-serif"; ctx.fillText(`Score: ${score}`, 10, 20); ctx.fillText(`High Score: ${highScore}`, 10, 40); if (isGameOver) { // "Game Over!" Text ctx.fillStyle = 'red'; - ctx.font = "20px 'Poppins', sans-serif"; + ctx.font = "18px 'Poppins', sans-serif"; const gameOverText = 'Game Over!'; const gameOverWidth = ctx.measureText(gameOverText).width; ctx.fillText(gameOverText, (canvas.width - gameOverWidth) / 2, canvas.height / 2 - 20); // Restart Instruction Text ctx.fillStyle = 'white'; - ctx.font = "16px 'Poppins', sans-serif"; + ctx.font = "10px 'Poppins', sans-serif"; const restartText = 'Press Space, Arrow Key, or Tap to Restart'; const restartWidth = ctx.measureText(restartText).width; ctx.fillText(restartText, (canvas.width - restartWidth) / 2, canvas.height / 2 + 10); diff --git a/MovieVerse-Frontend/js/highscores.js b/MovieVerse-Frontend/js/highscores.js index 9a3cacbc..7887e54d 100644 --- a/MovieVerse-Frontend/js/highscores.js +++ b/MovieVerse-Frontend/js/highscores.js @@ -54,6 +54,32 @@ const db = getFirestore(app); const games = ['BouncingStar', 'BucketGame', 'DinosaurJump', 'FlappyBird', 'SpaceShooter', 'StackGame']; +// Fetch user's high scores from Firebase and update local storage +async function syncHighScores() { + showSpinner(); + + const userEmail = localStorage.getItem('currentlySignedInMovieVerseUser'); + if (!userEmail) return; + + for (const game of games) { + const collectionRef = collection(db, `highScores${game}`); + const gameQuery = query(collectionRef, where('email', '==', userEmail)); + const snapshot = await getDocs(gameQuery); + + if (!snapshot.empty) { + const firebaseScore = snapshot.docs[0].data().score; + const localKey = `highScore${game}`; + const localScore = parseFloat(localStorage.getItem(localKey)) || 0; + + if (firebaseScore > localScore) { + localStorage.setItem(localKey, firebaseScore.toString()); + } + } + } + + hideSpinner(); +} + // Get local storage high scores function getLocalHighScores() { return games.reduce((scores, game) => { @@ -196,9 +222,27 @@ async function initializeLeaderboards() { leaderboardsContainer.innerHTML = ''; for (const [gameKey, data] of Object.entries(leaderboards)) { + let gameTitle = gameKey; + + if (gameKey === 'BouncingStar') { + gameTitle = 'Falling Star'; + } else if (gameKey === 'BucketGame') { + gameTitle = 'Catch the Popcorn'; + } else if (gameKey === 'DinosaurJump') { + gameTitle = 'Dinosaur Jump'; + } else if (gameKey === 'FlappyBird') { + gameTitle = 'Flappy Bird'; + } else if (gameKey === 'SpaceShooter') { + gameTitle = 'Space Invaders'; + } else if (gameKey === 'StackGame') { + gameTitle = 'Stack the Blocks'; + } else { + gameTitle = gameKey; + } + const container = document.createElement('div'); leaderboardsContainer.appendChild(container); // Attach container to DOM first - renderLeaderboard(container, gameKey, data, gameKey); // Render after attaching + renderLeaderboard(container, gameTitle, data, gameKey); // Render after attaching localStorage.setItem(`leaderboardData${gameKey}`, JSON.stringify(data)); updateLeaderboard(gameKey, data); // Safely update after rendering } @@ -206,5 +250,5 @@ async function initializeLeaderboards() { hideSpinner(); } -// Upload high scores and initialize leaderboards -uploadHighScores().then(initializeLeaderboards); +// Sync high scores, upload local scores, and initialize leaderboards +syncHighScores().then(uploadHighScores).then(initializeLeaderboards); diff --git a/MovieVerse-Mobile/app/js/dinosaur-jump.js b/MovieVerse-Mobile/app/js/dinosaur-jump.js index d626fa8d..22eacab5 100644 --- a/MovieVerse-Mobile/app/js/dinosaur-jump.js +++ b/MovieVerse-Mobile/app/js/dinosaur-jump.js @@ -134,21 +134,21 @@ function draw() { // Score ctx.fillStyle = 'white'; - ctx.font = "16px 'Poppins', sans-serif"; + ctx.font = "10px 'Poppins', sans-serif"; ctx.fillText(`Score: ${score}`, 10, 20); ctx.fillText(`High Score: ${highScore}`, 10, 40); if (isGameOver) { // "Game Over!" Text ctx.fillStyle = 'red'; - ctx.font = "20px 'Poppins', sans-serif"; + ctx.font = "18px 'Poppins', sans-serif"; const gameOverText = 'Game Over!'; const gameOverWidth = ctx.measureText(gameOverText).width; ctx.fillText(gameOverText, (canvas.width - gameOverWidth) / 2, canvas.height / 2 - 20); // Restart Instruction Text ctx.fillStyle = 'white'; - ctx.font = "16px 'Poppins', sans-serif"; + ctx.font = "10px 'Poppins', sans-serif"; const restartText = 'Press Space, Arrow Key, or Tap to Restart'; const restartWidth = ctx.measureText(restartText).width; ctx.fillText(restartText, (canvas.width - restartWidth) / 2, canvas.height / 2 + 10); diff --git a/MovieVerse-Mobile/app/js/highscores.js b/MovieVerse-Mobile/app/js/highscores.js index 9a3cacbc..7887e54d 100644 --- a/MovieVerse-Mobile/app/js/highscores.js +++ b/MovieVerse-Mobile/app/js/highscores.js @@ -54,6 +54,32 @@ const db = getFirestore(app); const games = ['BouncingStar', 'BucketGame', 'DinosaurJump', 'FlappyBird', 'SpaceShooter', 'StackGame']; +// Fetch user's high scores from Firebase and update local storage +async function syncHighScores() { + showSpinner(); + + const userEmail = localStorage.getItem('currentlySignedInMovieVerseUser'); + if (!userEmail) return; + + for (const game of games) { + const collectionRef = collection(db, `highScores${game}`); + const gameQuery = query(collectionRef, where('email', '==', userEmail)); + const snapshot = await getDocs(gameQuery); + + if (!snapshot.empty) { + const firebaseScore = snapshot.docs[0].data().score; + const localKey = `highScore${game}`; + const localScore = parseFloat(localStorage.getItem(localKey)) || 0; + + if (firebaseScore > localScore) { + localStorage.setItem(localKey, firebaseScore.toString()); + } + } + } + + hideSpinner(); +} + // Get local storage high scores function getLocalHighScores() { return games.reduce((scores, game) => { @@ -196,9 +222,27 @@ async function initializeLeaderboards() { leaderboardsContainer.innerHTML = ''; for (const [gameKey, data] of Object.entries(leaderboards)) { + let gameTitle = gameKey; + + if (gameKey === 'BouncingStar') { + gameTitle = 'Falling Star'; + } else if (gameKey === 'BucketGame') { + gameTitle = 'Catch the Popcorn'; + } else if (gameKey === 'DinosaurJump') { + gameTitle = 'Dinosaur Jump'; + } else if (gameKey === 'FlappyBird') { + gameTitle = 'Flappy Bird'; + } else if (gameKey === 'SpaceShooter') { + gameTitle = 'Space Invaders'; + } else if (gameKey === 'StackGame') { + gameTitle = 'Stack the Blocks'; + } else { + gameTitle = gameKey; + } + const container = document.createElement('div'); leaderboardsContainer.appendChild(container); // Attach container to DOM first - renderLeaderboard(container, gameKey, data, gameKey); // Render after attaching + renderLeaderboard(container, gameTitle, data, gameKey); // Render after attaching localStorage.setItem(`leaderboardData${gameKey}`, JSON.stringify(data)); updateLeaderboard(gameKey, data); // Safely update after rendering } @@ -206,5 +250,5 @@ async function initializeLeaderboards() { hideSpinner(); } -// Upload high scores and initialize leaderboards -uploadHighScores().then(initializeLeaderboards); +// Sync high scores, upload local scores, and initialize leaderboards +syncHighScores().then(uploadHighScores).then(initializeLeaderboards); diff --git a/MovieVerse-Mobile/platforms/android/app/src/main/assets/www/MovieVerse-Frontend/js/dinosaur-jump.js b/MovieVerse-Mobile/platforms/android/app/src/main/assets/www/MovieVerse-Frontend/js/dinosaur-jump.js index d626fa8d..22eacab5 100644 --- a/MovieVerse-Mobile/platforms/android/app/src/main/assets/www/MovieVerse-Frontend/js/dinosaur-jump.js +++ b/MovieVerse-Mobile/platforms/android/app/src/main/assets/www/MovieVerse-Frontend/js/dinosaur-jump.js @@ -134,21 +134,21 @@ function draw() { // Score ctx.fillStyle = 'white'; - ctx.font = "16px 'Poppins', sans-serif"; + ctx.font = "10px 'Poppins', sans-serif"; ctx.fillText(`Score: ${score}`, 10, 20); ctx.fillText(`High Score: ${highScore}`, 10, 40); if (isGameOver) { // "Game Over!" Text ctx.fillStyle = 'red'; - ctx.font = "20px 'Poppins', sans-serif"; + ctx.font = "18px 'Poppins', sans-serif"; const gameOverText = 'Game Over!'; const gameOverWidth = ctx.measureText(gameOverText).width; ctx.fillText(gameOverText, (canvas.width - gameOverWidth) / 2, canvas.height / 2 - 20); // Restart Instruction Text ctx.fillStyle = 'white'; - ctx.font = "16px 'Poppins', sans-serif"; + ctx.font = "10px 'Poppins', sans-serif"; const restartText = 'Press Space, Arrow Key, or Tap to Restart'; const restartWidth = ctx.measureText(restartText).width; ctx.fillText(restartText, (canvas.width - restartWidth) / 2, canvas.height / 2 + 10); diff --git a/MovieVerse-Mobile/platforms/android/app/src/main/assets/www/MovieVerse-Frontend/js/highscores.js b/MovieVerse-Mobile/platforms/android/app/src/main/assets/www/MovieVerse-Frontend/js/highscores.js index 9a3cacbc..7887e54d 100644 --- a/MovieVerse-Mobile/platforms/android/app/src/main/assets/www/MovieVerse-Frontend/js/highscores.js +++ b/MovieVerse-Mobile/platforms/android/app/src/main/assets/www/MovieVerse-Frontend/js/highscores.js @@ -54,6 +54,32 @@ const db = getFirestore(app); const games = ['BouncingStar', 'BucketGame', 'DinosaurJump', 'FlappyBird', 'SpaceShooter', 'StackGame']; +// Fetch user's high scores from Firebase and update local storage +async function syncHighScores() { + showSpinner(); + + const userEmail = localStorage.getItem('currentlySignedInMovieVerseUser'); + if (!userEmail) return; + + for (const game of games) { + const collectionRef = collection(db, `highScores${game}`); + const gameQuery = query(collectionRef, where('email', '==', userEmail)); + const snapshot = await getDocs(gameQuery); + + if (!snapshot.empty) { + const firebaseScore = snapshot.docs[0].data().score; + const localKey = `highScore${game}`; + const localScore = parseFloat(localStorage.getItem(localKey)) || 0; + + if (firebaseScore > localScore) { + localStorage.setItem(localKey, firebaseScore.toString()); + } + } + } + + hideSpinner(); +} + // Get local storage high scores function getLocalHighScores() { return games.reduce((scores, game) => { @@ -196,9 +222,27 @@ async function initializeLeaderboards() { leaderboardsContainer.innerHTML = ''; for (const [gameKey, data] of Object.entries(leaderboards)) { + let gameTitle = gameKey; + + if (gameKey === 'BouncingStar') { + gameTitle = 'Falling Star'; + } else if (gameKey === 'BucketGame') { + gameTitle = 'Catch the Popcorn'; + } else if (gameKey === 'DinosaurJump') { + gameTitle = 'Dinosaur Jump'; + } else if (gameKey === 'FlappyBird') { + gameTitle = 'Flappy Bird'; + } else if (gameKey === 'SpaceShooter') { + gameTitle = 'Space Invaders'; + } else if (gameKey === 'StackGame') { + gameTitle = 'Stack the Blocks'; + } else { + gameTitle = gameKey; + } + const container = document.createElement('div'); leaderboardsContainer.appendChild(container); // Attach container to DOM first - renderLeaderboard(container, gameKey, data, gameKey); // Render after attaching + renderLeaderboard(container, gameTitle, data, gameKey); // Render after attaching localStorage.setItem(`leaderboardData${gameKey}`, JSON.stringify(data)); updateLeaderboard(gameKey, data); // Safely update after rendering } @@ -206,5 +250,5 @@ async function initializeLeaderboards() { hideSpinner(); } -// Upload high scores and initialize leaderboards -uploadHighScores().then(initializeLeaderboards); +// Sync high scores, upload local scores, and initialize leaderboards +syncHighScores().then(uploadHighScores).then(initializeLeaderboards); diff --git a/MovieVerse-Mobile/platforms/ios/www/MovieVerse-Frontend/js/dinosaur-jump.js b/MovieVerse-Mobile/platforms/ios/www/MovieVerse-Frontend/js/dinosaur-jump.js index d626fa8d..22eacab5 100644 --- a/MovieVerse-Mobile/platforms/ios/www/MovieVerse-Frontend/js/dinosaur-jump.js +++ b/MovieVerse-Mobile/platforms/ios/www/MovieVerse-Frontend/js/dinosaur-jump.js @@ -134,21 +134,21 @@ function draw() { // Score ctx.fillStyle = 'white'; - ctx.font = "16px 'Poppins', sans-serif"; + ctx.font = "10px 'Poppins', sans-serif"; ctx.fillText(`Score: ${score}`, 10, 20); ctx.fillText(`High Score: ${highScore}`, 10, 40); if (isGameOver) { // "Game Over!" Text ctx.fillStyle = 'red'; - ctx.font = "20px 'Poppins', sans-serif"; + ctx.font = "18px 'Poppins', sans-serif"; const gameOverText = 'Game Over!'; const gameOverWidth = ctx.measureText(gameOverText).width; ctx.fillText(gameOverText, (canvas.width - gameOverWidth) / 2, canvas.height / 2 - 20); // Restart Instruction Text ctx.fillStyle = 'white'; - ctx.font = "16px 'Poppins', sans-serif"; + ctx.font = "10px 'Poppins', sans-serif"; const restartText = 'Press Space, Arrow Key, or Tap to Restart'; const restartWidth = ctx.measureText(restartText).width; ctx.fillText(restartText, (canvas.width - restartWidth) / 2, canvas.height / 2 + 10); diff --git a/MovieVerse-Mobile/platforms/ios/www/MovieVerse-Frontend/js/highscores.js b/MovieVerse-Mobile/platforms/ios/www/MovieVerse-Frontend/js/highscores.js index 9a3cacbc..7887e54d 100644 --- a/MovieVerse-Mobile/platforms/ios/www/MovieVerse-Frontend/js/highscores.js +++ b/MovieVerse-Mobile/platforms/ios/www/MovieVerse-Frontend/js/highscores.js @@ -54,6 +54,32 @@ const db = getFirestore(app); const games = ['BouncingStar', 'BucketGame', 'DinosaurJump', 'FlappyBird', 'SpaceShooter', 'StackGame']; +// Fetch user's high scores from Firebase and update local storage +async function syncHighScores() { + showSpinner(); + + const userEmail = localStorage.getItem('currentlySignedInMovieVerseUser'); + if (!userEmail) return; + + for (const game of games) { + const collectionRef = collection(db, `highScores${game}`); + const gameQuery = query(collectionRef, where('email', '==', userEmail)); + const snapshot = await getDocs(gameQuery); + + if (!snapshot.empty) { + const firebaseScore = snapshot.docs[0].data().score; + const localKey = `highScore${game}`; + const localScore = parseFloat(localStorage.getItem(localKey)) || 0; + + if (firebaseScore > localScore) { + localStorage.setItem(localKey, firebaseScore.toString()); + } + } + } + + hideSpinner(); +} + // Get local storage high scores function getLocalHighScores() { return games.reduce((scores, game) => { @@ -196,9 +222,27 @@ async function initializeLeaderboards() { leaderboardsContainer.innerHTML = ''; for (const [gameKey, data] of Object.entries(leaderboards)) { + let gameTitle = gameKey; + + if (gameKey === 'BouncingStar') { + gameTitle = 'Falling Star'; + } else if (gameKey === 'BucketGame') { + gameTitle = 'Catch the Popcorn'; + } else if (gameKey === 'DinosaurJump') { + gameTitle = 'Dinosaur Jump'; + } else if (gameKey === 'FlappyBird') { + gameTitle = 'Flappy Bird'; + } else if (gameKey === 'SpaceShooter') { + gameTitle = 'Space Invaders'; + } else if (gameKey === 'StackGame') { + gameTitle = 'Stack the Blocks'; + } else { + gameTitle = gameKey; + } + const container = document.createElement('div'); leaderboardsContainer.appendChild(container); // Attach container to DOM first - renderLeaderboard(container, gameKey, data, gameKey); // Render after attaching + renderLeaderboard(container, gameTitle, data, gameKey); // Render after attaching localStorage.setItem(`leaderboardData${gameKey}`, JSON.stringify(data)); updateLeaderboard(gameKey, data); // Safely update after rendering } @@ -206,5 +250,5 @@ async function initializeLeaderboards() { hideSpinner(); } -// Upload high scores and initialize leaderboards -uploadHighScores().then(initializeLeaderboards); +// Sync high scores, upload local scores, and initialize leaderboards +syncHighScores().then(uploadHighScores).then(initializeLeaderboards); diff --git a/MovieVerse-Mobile/www/MovieVerse-Frontend/js/dinosaur-jump.js b/MovieVerse-Mobile/www/MovieVerse-Frontend/js/dinosaur-jump.js index d626fa8d..22eacab5 100644 --- a/MovieVerse-Mobile/www/MovieVerse-Frontend/js/dinosaur-jump.js +++ b/MovieVerse-Mobile/www/MovieVerse-Frontend/js/dinosaur-jump.js @@ -134,21 +134,21 @@ function draw() { // Score ctx.fillStyle = 'white'; - ctx.font = "16px 'Poppins', sans-serif"; + ctx.font = "10px 'Poppins', sans-serif"; ctx.fillText(`Score: ${score}`, 10, 20); ctx.fillText(`High Score: ${highScore}`, 10, 40); if (isGameOver) { // "Game Over!" Text ctx.fillStyle = 'red'; - ctx.font = "20px 'Poppins', sans-serif"; + ctx.font = "18px 'Poppins', sans-serif"; const gameOverText = 'Game Over!'; const gameOverWidth = ctx.measureText(gameOverText).width; ctx.fillText(gameOverText, (canvas.width - gameOverWidth) / 2, canvas.height / 2 - 20); // Restart Instruction Text ctx.fillStyle = 'white'; - ctx.font = "16px 'Poppins', sans-serif"; + ctx.font = "10px 'Poppins', sans-serif"; const restartText = 'Press Space, Arrow Key, or Tap to Restart'; const restartWidth = ctx.measureText(restartText).width; ctx.fillText(restartText, (canvas.width - restartWidth) / 2, canvas.height / 2 + 10); diff --git a/MovieVerse-Mobile/www/MovieVerse-Frontend/js/highscores.js b/MovieVerse-Mobile/www/MovieVerse-Frontend/js/highscores.js index 9a3cacbc..7887e54d 100644 --- a/MovieVerse-Mobile/www/MovieVerse-Frontend/js/highscores.js +++ b/MovieVerse-Mobile/www/MovieVerse-Frontend/js/highscores.js @@ -54,6 +54,32 @@ const db = getFirestore(app); const games = ['BouncingStar', 'BucketGame', 'DinosaurJump', 'FlappyBird', 'SpaceShooter', 'StackGame']; +// Fetch user's high scores from Firebase and update local storage +async function syncHighScores() { + showSpinner(); + + const userEmail = localStorage.getItem('currentlySignedInMovieVerseUser'); + if (!userEmail) return; + + for (const game of games) { + const collectionRef = collection(db, `highScores${game}`); + const gameQuery = query(collectionRef, where('email', '==', userEmail)); + const snapshot = await getDocs(gameQuery); + + if (!snapshot.empty) { + const firebaseScore = snapshot.docs[0].data().score; + const localKey = `highScore${game}`; + const localScore = parseFloat(localStorage.getItem(localKey)) || 0; + + if (firebaseScore > localScore) { + localStorage.setItem(localKey, firebaseScore.toString()); + } + } + } + + hideSpinner(); +} + // Get local storage high scores function getLocalHighScores() { return games.reduce((scores, game) => { @@ -196,9 +222,27 @@ async function initializeLeaderboards() { leaderboardsContainer.innerHTML = ''; for (const [gameKey, data] of Object.entries(leaderboards)) { + let gameTitle = gameKey; + + if (gameKey === 'BouncingStar') { + gameTitle = 'Falling Star'; + } else if (gameKey === 'BucketGame') { + gameTitle = 'Catch the Popcorn'; + } else if (gameKey === 'DinosaurJump') { + gameTitle = 'Dinosaur Jump'; + } else if (gameKey === 'FlappyBird') { + gameTitle = 'Flappy Bird'; + } else if (gameKey === 'SpaceShooter') { + gameTitle = 'Space Invaders'; + } else if (gameKey === 'StackGame') { + gameTitle = 'Stack the Blocks'; + } else { + gameTitle = gameKey; + } + const container = document.createElement('div'); leaderboardsContainer.appendChild(container); // Attach container to DOM first - renderLeaderboard(container, gameKey, data, gameKey); // Render after attaching + renderLeaderboard(container, gameTitle, data, gameKey); // Render after attaching localStorage.setItem(`leaderboardData${gameKey}`, JSON.stringify(data)); updateLeaderboard(gameKey, data); // Safely update after rendering } @@ -206,5 +250,5 @@ async function initializeLeaderboards() { hideSpinner(); } -// Upload high scores and initialize leaderboards -uploadHighScores().then(initializeLeaderboards); +// Sync high scores, upload local scores, and initialize leaderboards +syncHighScores().then(uploadHighScores).then(initializeLeaderboards); diff --git a/MovieVerse-Mobile/www/js/dinosaur-jump.js b/MovieVerse-Mobile/www/js/dinosaur-jump.js index d626fa8d..22eacab5 100644 --- a/MovieVerse-Mobile/www/js/dinosaur-jump.js +++ b/MovieVerse-Mobile/www/js/dinosaur-jump.js @@ -134,21 +134,21 @@ function draw() { // Score ctx.fillStyle = 'white'; - ctx.font = "16px 'Poppins', sans-serif"; + ctx.font = "10px 'Poppins', sans-serif"; ctx.fillText(`Score: ${score}`, 10, 20); ctx.fillText(`High Score: ${highScore}`, 10, 40); if (isGameOver) { // "Game Over!" Text ctx.fillStyle = 'red'; - ctx.font = "20px 'Poppins', sans-serif"; + ctx.font = "18px 'Poppins', sans-serif"; const gameOverText = 'Game Over!'; const gameOverWidth = ctx.measureText(gameOverText).width; ctx.fillText(gameOverText, (canvas.width - gameOverWidth) / 2, canvas.height / 2 - 20); // Restart Instruction Text ctx.fillStyle = 'white'; - ctx.font = "16px 'Poppins', sans-serif"; + ctx.font = "10px 'Poppins', sans-serif"; const restartText = 'Press Space, Arrow Key, or Tap to Restart'; const restartWidth = ctx.measureText(restartText).width; ctx.fillText(restartText, (canvas.width - restartWidth) / 2, canvas.height / 2 + 10); diff --git a/MovieVerse-Mobile/www/js/highscores.js b/MovieVerse-Mobile/www/js/highscores.js index 9a3cacbc..7887e54d 100644 --- a/MovieVerse-Mobile/www/js/highscores.js +++ b/MovieVerse-Mobile/www/js/highscores.js @@ -54,6 +54,32 @@ const db = getFirestore(app); const games = ['BouncingStar', 'BucketGame', 'DinosaurJump', 'FlappyBird', 'SpaceShooter', 'StackGame']; +// Fetch user's high scores from Firebase and update local storage +async function syncHighScores() { + showSpinner(); + + const userEmail = localStorage.getItem('currentlySignedInMovieVerseUser'); + if (!userEmail) return; + + for (const game of games) { + const collectionRef = collection(db, `highScores${game}`); + const gameQuery = query(collectionRef, where('email', '==', userEmail)); + const snapshot = await getDocs(gameQuery); + + if (!snapshot.empty) { + const firebaseScore = snapshot.docs[0].data().score; + const localKey = `highScore${game}`; + const localScore = parseFloat(localStorage.getItem(localKey)) || 0; + + if (firebaseScore > localScore) { + localStorage.setItem(localKey, firebaseScore.toString()); + } + } + } + + hideSpinner(); +} + // Get local storage high scores function getLocalHighScores() { return games.reduce((scores, game) => { @@ -196,9 +222,27 @@ async function initializeLeaderboards() { leaderboardsContainer.innerHTML = ''; for (const [gameKey, data] of Object.entries(leaderboards)) { + let gameTitle = gameKey; + + if (gameKey === 'BouncingStar') { + gameTitle = 'Falling Star'; + } else if (gameKey === 'BucketGame') { + gameTitle = 'Catch the Popcorn'; + } else if (gameKey === 'DinosaurJump') { + gameTitle = 'Dinosaur Jump'; + } else if (gameKey === 'FlappyBird') { + gameTitle = 'Flappy Bird'; + } else if (gameKey === 'SpaceShooter') { + gameTitle = 'Space Invaders'; + } else if (gameKey === 'StackGame') { + gameTitle = 'Stack the Blocks'; + } else { + gameTitle = gameKey; + } + const container = document.createElement('div'); leaderboardsContainer.appendChild(container); // Attach container to DOM first - renderLeaderboard(container, gameKey, data, gameKey); // Render after attaching + renderLeaderboard(container, gameTitle, data, gameKey); // Render after attaching localStorage.setItem(`leaderboardData${gameKey}`, JSON.stringify(data)); updateLeaderboard(gameKey, data); // Safely update after rendering } @@ -206,5 +250,5 @@ async function initializeLeaderboards() { hideSpinner(); } -// Upload high scores and initialize leaderboards -uploadHighScores().then(initializeLeaderboards); +// Sync high scores, upload local scores, and initialize leaderboards +syncHighScores().then(uploadHighScores).then(initializeLeaderboards);