diff --git a/css/game.css b/css/game.css index 9d33e74..921bd93 100644 --- a/css/game.css +++ b/css/game.css @@ -129,7 +129,7 @@ body, html { cursor: pointer; outline: none; position: absolute; - top: 100%; /* Centrar en la pantalla para móviles */ + /*top: 100%; !* Centrar en la pantalla para móviles *!*/ left: 45%; transform: translate(-50%, -50%); /* Centrar precisamente el botón */ z-index: 10; @@ -244,3 +244,65 @@ body, html { .legal-text li { margin-bottom: 10px; } + + +.modal { + /* Estilos existentes para el modal */ +} + +.modal h2, .modal h3 { + font-family: 'Press Start 2P', cursive; /* Ejemplo de fuente estilo retro */ +} + +#playerInitials { + background-color: transparent; /* Fondo transparente */ + color: white; /* Texto en color blanco */ + border: none; /* Sin borde */ + outline: none; /* Eliminar el outline que aparece al hacer foco */ + font-size: 50px; /* Tamaño de fuente grande */ + text-align: center; /* Centrar texto */ + font-family: 'Press Start 2P', cursive; /* Fuente estilo arcade, asegúrate de cargarla */ + width: 100%; /* Ancho completo para ocupar el espacio disponible */ + max-width: 400px; /* Máximo ancho que puede tener */ + margin: 0 auto; /* Margen automático para centrar el input */ +} + +#saveScoreButton { + background-color: transparent; /* Fondo transparente */ + color: white; /* Texto en color blanco */ + border: 2px solid white; /* Borde blanco para el botón */ + font-family: 'Press Start 2P', cursive; /* Fuente estilo arcade */ + font-size: 20px; /* Tamaño de fuente adecuado para el botón */ + padding: 10px 20px; /* Padding para hacer el botón más grande */ + cursor: pointer; /* Cambiar el cursor a pointer para indicar que es clickeable */ + outline: none; /* Eliminar el outline que aparece al hacer foco */ + margin-top: 20px; /* Espacio arriba del botón */ +} + +#scoreList { + max-height: 400px; /* O la altura que prefieras */ + overflow-y: auto; /* Muestra un scrollbar si es necesario */ + padding: 0; /* Remueve el padding por defecto */ + list-style: none; /* Opcional: remueve los estilos por defecto de lista */ + width: 100%; /* Ajusta el ancho según necesites */ + box-sizing: border-box; +} + +#scoreList li { + color: #FFFFFF; + font-family: 'Press Start 2P'; + font-size: 50px; + padding: 5px 10px; /* Añade padding para cada entrada */ + border-bottom: 1px solid #ccc; /* Opcional: añade una línea entre entradas */ +} + +.p-white-start-p2 { + font-size: 20px; + color: #FFFFFF; + font-family: 'Press Start 2P'; + font-size: 30px; + color: white; + font-family: 'Press Start 2P'; + margin-left: 10%; + padding-top: 10%; +} \ No newline at end of file diff --git a/index.html b/index.html index e338d17..adb23ba 100644 --- a/index.html +++ b/index.html @@ -12,12 +12,17 @@
Disparos: 50
+
Score:
-
Score:
@@ -41,5 +46,9 @@ + + + + \ No newline at end of file diff --git a/js/FirebaseManager.js b/js/FirebaseManager.js new file mode 100644 index 0000000..298d4f8 --- /dev/null +++ b/js/FirebaseManager.js @@ -0,0 +1,42 @@ +export default class FirebaseManager { + constructor() { + // Your web app's Firebase configuration + const firebaseConfig = { + apiKey: "AIzaSyASSEoYYNf-jb5FlSbq9Fj5CNxj4X-69_I", + authDomain: "puchis-adventure.firebaseapp.com", + projectId: "puchis-adventure", + storageBucket: "puchis-adventure.appspot.com", + messagingSenderId: "836031237974", + appId: "1:836031237974:web:81d54b55d78025b39cd0f7" + }; + firebase.initializeApp(firebaseConfig); + + this.db = firebase.firestore(); + } + + async addScore(initials, score) { + try { + await this.db.collection("scores").add({ + initials, + score, + timestamp: firebase.firestore.FieldValue.serverTimestamp() + }); + } catch (error) { + console.error("Error adding score to Firebase", error); + } + } + + async getScores() { + try { + const scoresSnapshot = await this.db.collection("scores") + .orderBy("score", "desc") + .limit(50) + .get(); + + return scoresSnapshot.docs.map(doc => doc.data()); + } catch (error) { + console.error("Error fetching scores from Firebase", error); + return []; + } + } +} diff --git a/js/Game.js b/js/Game.js index ab4fc2e..d4bfd31 100644 --- a/js/Game.js +++ b/js/Game.js @@ -4,8 +4,9 @@ import Ray from './Ray.js'; import Enemy from "./Enemy.js"; import Explosion from "./Explosion.js"; import AmmoPowerUp from "./PowerUps/AmmoPowerUp.js"; +import {updateRanking} from './Services/Ranking.js'; -class Game { +export default class Game { constructor(canvasId) { this.canvas = document.getElementById(canvasId); @@ -219,6 +220,7 @@ class Game { // Manejar el fin del juego this.running = false; this.showGameOver(); + this.showRankingScore(); } resetGame() { @@ -265,6 +267,7 @@ class Game { showGameOver() { // Muestra la imagen de Game Over y el botón de reinicio document.getElementById('gameOverContainer').style.display = 'block'; + document.getElementById('playerInitials').focus(); document.getElementById('restartButton').style.display = 'block'; this.running = false; // Detiene el juego } @@ -302,12 +305,21 @@ class Game { this.powerUps.push(new AmmoPowerUp(this.ctx, x, y)); } + // ... + showRankingScore() { + let game = this; + updateRanking(game); + } + + getCurrentScore() { + return this.score; + } } // Inicializar el juego +const game = new Game('gameCanvas'); document.addEventListener('DOMContentLoaded', () => { new Galaxy('galaxy'); - const game = new Game('gameCanvas'); game.resetGame(); game.resizeCanvas(); const start_buttons = document.getElementsByClassName('game-button'); diff --git a/js/RankingManager.js b/js/RankingManager.js new file mode 100644 index 0000000..1b71d75 --- /dev/null +++ b/js/RankingManager.js @@ -0,0 +1,69 @@ +import Game from './Game.js'; + +export default class RankingManager { + constructor(firebaseManager) { + this.firebaseManager = firebaseManager; + this.scores = []; + } + + async getScoresFromFirebase() { + this.scores = await this.firebaseManager.getScores(); + this.renderScores(); + } + + addNewScore(initials, score) { + this.firebaseManager.addScore(initials, score) + .then(() => this.getScoresFromFirebase()) + .catch(error => console.error("Error adding new score", error)); + } + + renderScores() { + this.formatRanking(); + } + + async updateRankingUI() { + await this.getScoresFromFirebase(); // Asume que este método obtiene las puntuaciones de Firebase + this.formatRanking(); + } + + formatRanking() { + const rankingList = document.getElementById('scoreList'); + rankingList.innerHTML = ''; // Limpia la lista actual + + this.scores.forEach((score, index) => { + const listItem = document.createElement('li'); + let points = parseInt(score.score); + let score_text = score.score.toString(); + if (0 < points) { + score_text = score_text.replace(/\B(?=(\d{3})+(?!\d))/g, ".") + } + listItem.textContent = `${score.initials}: ${score_text}`; + rankingList.appendChild(listItem); + }); + } +} + + +// Asegúrate de que el DOM esté completamente cargado antes de ejecutar tu script +document.addEventListener('DOMContentLoaded', function () { + // Aquí puedes instanciar y configurar tu juego y rankingManager + const game = new Game(); + const rankingManager = new RankingManager(); + let isSaveButtonEventAttached = false; + if (isSaveButtonEventAttached) return; + + // Configurar el manejador del evento click para el botón de guardar + document.getElementById('saveScoreButton').addEventListener('click', async function () { + const initials = document.getElementById('playerInitials').value; + initials.focus(); + const score = game.getCurrentScore(); // Suponiendo que esta función existe en game.js + + if (initials && null !== score) { + await rankingManager.addNewScore(initials, score); + await rankingManager.updateScores(); // Esto actualizará y mostrará el ranking + } + }); + isSaveButtonEventAttached = true; + + // Aquí puedes incluir cualquier otra configuración inicial +}); diff --git a/js/Services/Ranking.js b/js/Services/Ranking.js new file mode 100644 index 0000000..36ece1b --- /dev/null +++ b/js/Services/Ranking.js @@ -0,0 +1,22 @@ +// RankingIntegration.js +import FirebaseManager from '../FirebaseManager.js'; +import RankingManager from '../RankingManager.js'; + +const firebaseManager = new FirebaseManager(); +const rankingManager = new RankingManager(firebaseManager); + +export async function updateRanking(game) { + document.getElementById('saveScoreButton').addEventListener('click', function () { + const initials = document.getElementById('playerInitials').value; + const score = game.getCurrentScore(); + + // Guardar la puntuación en Firebase y actualizar el ranking + rankingManager.addNewScore(initials, score); + }); + rankingManager.getScoresFromFirebase(); + await rankingManager.updateRankingUI(); // Actualiza y muestra el ranking +} + +export function submitScore(initials, score) { + rankingManager.addNewScore(initials, score); +}