Skip to content

Commit

Permalink
feat: Add Ranking using Firebase
Browse files Browse the repository at this point in the history
  • Loading branch information
povedica committed Nov 25, 2023
1 parent a45dd41 commit f224147
Show file tree
Hide file tree
Showing 6 changed files with 220 additions and 4 deletions.
64 changes: 63 additions & 1 deletion css/game.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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%;
}
11 changes: 10 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,17 @@
<div id="gameContainer">
<div id="shotsLeft">Disparos: <span id="shotsLeftCount">50</span></div>
<canvas id="gameCanvas" width="100%" height="100%"></canvas>
<div id="scorePanel">Score: <span id="score"></span></div>
<div id="gameOverContainer" style="display: none;">
<img id="gameOverImage" src="images/game-over-puchi.png" alt="Game Over"/>
<button class="game-button game-blue-button" id="restartButton">Volver a empezar</button>
<p class="p-white-start-p2">Introduce tus iniciales:</p>
<input type="text" id="playerInitials" maxlength="3" />
<button id="saveScoreButton">Guardar</button>
<h3>Ranking</h3>
<ol id="scoreList"></ol>
</div>
<button class="game-button game-blue-button center-button" id="startButton">Inicio</button>
<div id="scorePanel">Score: <span id="score"></span></div>
</div>
</div>
<!-- Enlace en el Popup de Cookies -->
Expand All @@ -41,5 +46,9 @@
<script async type="application/javascript" src="js/CookieLegal.js"></script>
<script type="application/javascript" src="js/GameConfig.js"></script>
<script type="module" src="js/Game.js"></script>
<script type="module" src="js/RankingManager.js"></script>
<!-- Agrega Firebase SDKs y Firebase Initialization aquí -->
<script async src="https://www.gstatic.com/firebasejs/8.6.8/firebase-app.js"></script>
<script async src="https://www.gstatic.com/firebasejs/8.6.8/firebase-firestore.js"></script>
</body>
</html>
42 changes: 42 additions & 0 deletions js/FirebaseManager.js
Original file line number Diff line number Diff line change
@@ -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 [];
}
}
}
16 changes: 14 additions & 2 deletions js/Game.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -219,6 +220,7 @@ class Game {
// Manejar el fin del juego
this.running = false;
this.showGameOver();
this.showRankingScore();
}

resetGame() {
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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');
Expand Down
69 changes: 69 additions & 0 deletions js/RankingManager.js
Original file line number Diff line number Diff line change
@@ -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
});
22 changes: 22 additions & 0 deletions js/Services/Ranking.js
Original file line number Diff line number Diff line change
@@ -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);
}

0 comments on commit f224147

Please sign in to comment.