reset UUID y shame persistente
This commit is contained in:
@@ -1,5 +1,20 @@
|
||||
<template>
|
||||
<div class="game">
|
||||
<!-- End of game modal overlay -->
|
||||
<div v-if="endModal.visible" class="end-modal-overlay" @click.self="dismissEndModal">
|
||||
<div class="end-modal">
|
||||
<button class="close-btn" @click="dismissEndModal" aria-label="Cerrar">×</button>
|
||||
<div class="title">🏁 Juego finalizado</div>
|
||||
<div class="scores">
|
||||
<div v-for="s in finalScores" :key="s.sessionId" class="score-row">
|
||||
<span class="name">{{ s.name }}</span>
|
||||
<span class="tokens">🦃 {{ s.pavo }} · 🌽 {{ s.elote }}</span>
|
||||
<span class="points">Puntos: {{ s.points }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hint">Se cerrará en {{ remainingSeconds }}s</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="game-container">
|
||||
<div class="game-header">
|
||||
<h1>🧪 Demo Room</h1>
|
||||
@@ -99,6 +114,58 @@ const outcomeP2 = ref(0);
|
||||
|
||||
const variants = ['G1','G2','G3','G4','G5'];
|
||||
|
||||
// End-of-game modal state and helpers
|
||||
const endModal = ref<{ visible: boolean }>({ visible: false });
|
||||
const remainingSeconds = ref(10);
|
||||
let endTimerTimeout: any = null;
|
||||
let endTimerInterval: any = null;
|
||||
|
||||
function showEndModal() {
|
||||
// Prevent multiple timers
|
||||
if (endModal.value.visible) return;
|
||||
endModal.value.visible = true;
|
||||
remainingSeconds.value = 10;
|
||||
if (endTimerInterval) clearInterval(endTimerInterval);
|
||||
if (endTimerTimeout) clearTimeout(endTimerTimeout);
|
||||
endTimerInterval = setInterval(() => {
|
||||
remainingSeconds.value = Math.max(0, remainingSeconds.value - 1);
|
||||
}, 1000);
|
||||
endTimerTimeout = setTimeout(() => {
|
||||
dismissEndModal();
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
function dismissEndModal() {
|
||||
endModal.value.visible = false;
|
||||
if (endTimerInterval) { clearInterval(endTimerInterval); endTimerInterval = null; }
|
||||
if (endTimerTimeout) { clearTimeout(endTimerTimeout); endTimerTimeout = null; }
|
||||
}
|
||||
|
||||
const finalScores = computed(() => {
|
||||
return players.value.map(p => {
|
||||
const points = (p.role === 'P2')
|
||||
? (p.eloteTokens || 0) * 1 + (p.pavoTokens || 0) * 2
|
||||
: (p.pavoTokens || 0) * 1 + (p.eloteTokens || 0) * 2;
|
||||
return {
|
||||
sessionId: p.sessionId,
|
||||
name: p.name,
|
||||
pavo: p.pavoTokens || 0,
|
||||
elote: p.eloteTokens || 0,
|
||||
points
|
||||
};
|
||||
}).sort((a, b) => b.points - a.points);
|
||||
});
|
||||
|
||||
// Round transition banner state and helper
|
||||
const roundBanner = ref<{ visible: boolean; text: string; kind: 'start'|'end' }>({ visible: false, text: '', kind: 'start' });
|
||||
let roundBannerTimeout: any = null;
|
||||
|
||||
function showRoundBanner(text: string, kind: 'start'|'end', ms = 1400) {
|
||||
if (roundBannerTimeout) { clearTimeout(roundBannerTimeout); roundBannerTimeout = null; }
|
||||
roundBanner.value = { visible: true, text, kind };
|
||||
roundBannerTimeout = setTimeout(() => { roundBanner.value.visible = false; }, ms);
|
||||
}
|
||||
|
||||
const sessionId = computed(() => colyseusService.sessionId.value);
|
||||
const myRole = computed(() => {
|
||||
const me = players.value.find(p => p.sessionId === sessionId.value);
|
||||
@@ -141,7 +208,12 @@ onMounted(() => {
|
||||
gameStatus.value = state.gameStatus || 'waiting';
|
||||
});
|
||||
|
||||
$(room.state).listen("gameStatus", (value: string) => { gameStatus.value = value; });
|
||||
$(room.state).listen("gameStatus", (value: string) => {
|
||||
gameStatus.value = value;
|
||||
if ((value || '').toLowerCase() === 'finished') {
|
||||
showEndModal();
|
||||
}
|
||||
});
|
||||
$(room.state).listen("roomId", (value: string) => { roomId.value = value; });
|
||||
$(room.state).listen("currentVariant", (value: string) => { currentVariant.value = value as any; });
|
||||
$(room.state).listen("currentRound", (value: number) => { currentRound.value = value; });
|
||||
@@ -186,9 +258,7 @@ onMounted(() => {
|
||||
colyseusService.playerName.value = info.name;
|
||||
});
|
||||
|
||||
room.onMessage("gameEnd", () => {
|
||||
// no-op for local storage
|
||||
});
|
||||
room.onMessage("gameEnd", () => { showEndModal(); });
|
||||
|
||||
// Register additional message handlers to avoid warnings
|
||||
room.onMessage("gamePaused", () => {
|
||||
@@ -203,6 +273,8 @@ onMounted(() => {
|
||||
currentVariant.value = data.variant as any;
|
||||
});
|
||||
|
||||
// No round transition banners
|
||||
|
||||
// Handle room closure/disconnection
|
||||
room.onLeave((code: number) => {
|
||||
console.log('[DemoGame] Room disconnected with code:', code);
|
||||
@@ -266,6 +338,17 @@ function leaveGame() {
|
||||
|
||||
<style scoped>
|
||||
.game { min-height: 100vh; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); display:flex; align-items:center; justify-content:center; padding:20px; }
|
||||
.end-modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.55); display:flex; align-items:center; justify-content:center; z-index: 1200; }
|
||||
.end-modal { position: relative; background: white; color:#111; border-radius: 16px; padding: 24px 24px 18px; width: min(520px, 92vw); box-shadow: 0 30px 80px rgba(0,0,0,0.5); border:1px solid #e5e7eb; }
|
||||
.end-modal .close-btn { position:absolute; top:8px; right:8px; width:32px; height:32px; border-radius: 8px; border:1px solid #e5e7eb; background:#f8fafc; color:#111; font-weight:800; cursor:pointer; }
|
||||
.end-modal .close-btn:hover { background:#eef2ff; }
|
||||
.end-modal .title { font-size: 20px; font-weight: 900; margin-bottom: 8px; }
|
||||
.end-modal .scores { display:flex; flex-direction:column; gap:8px; margin: 8px 0 12px; }
|
||||
.end-modal .score-row { display:flex; align-items:center; justify-content:space-between; gap:8px; background:#f8fafc; border:1px solid #e5e7eb; border-radius: 10px; padding:8px 10px; }
|
||||
.end-modal .score-row .name { font-weight:800; color:#1f2937; }
|
||||
.end-modal .score-row .tokens { font-weight:700; color:#374151; }
|
||||
.end-modal .score-row .points { font-weight:900; color:#111827; }
|
||||
.end-modal .hint { font-size: 12px; color:#6b7280; text-align:right; }
|
||||
.game-container { background: white; border-radius: 20px; padding: 24px; max-width: 1000px; width: 100%; box-shadow: 0 20px 60px rgba(0,0,0,0.3); }
|
||||
.game-header { display:flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
|
||||
.game-header h1 { margin: 0; font-size: 20px; }
|
||||
|
||||
Reference in New Issue
Block a user