feat: modo multidispositivo con Nearby Connections
All checks were successful
Build & Deploy Farolero / Análisis de código (push) Successful in 9s
Build & Deploy Farolero / Build APK + AAB release (push) Successful in 1m10s

- ServicioNearby completo: P2P_STAR, auto-accept, protocolo mensajes
- PantallaLobbyHost: QR code + lista jugadores tiempo real
- PantallaUnirse: escaneo QR + conexión + sala espera
- Protocolo MensajeP2P: salaInfo, partidaInicio, fase, voto, resultado, fin
- Manejo desconexiones jugador/host
- l10n: nuevas keys es/en
- Version bump 1.1.0+5
This commit is contained in:
ShanaiaBot
2026-04-04 03:09:51 +02:00
parent f453ce6e0d
commit 23472707ad
25 changed files with 1799 additions and 165 deletions

View File

@@ -1,20 +1,16 @@
{
"@@locale": "es",
"appTitle": "Farolero",
"subtitle": "Juego de deducción social",
"loadingWords": "Cargando palabras...",
"playersRange": "3-20 jugadores • Sin internet",
"createGame": "Crear partida",
"joinGame": "Unirse a partida",
"howToPlay": "Cómo jugar",
"settings": "Ajustes",
"gameMode": "Modo de juego",
"singleDevice": "Un solo móvil",
"multiDevice": "Multimóvil",
"category": "Categoría",
"categoryAll": "Todas",
"categoryAnimals": "Animales",
@@ -27,11 +23,12 @@
"categoryMovies": "Películas",
"categoryMusic": "Música",
"categoryTechnology": "Tecnología",
"playersCount": "Jugadores ({count})",
"@playersCount": {
"placeholders": {
"count": {"type": "int"}
"count": {
"type": "int"
}
}
},
"playersRangeHint": "3-20",
@@ -39,7 +36,6 @@
"playerAlreadyExists": "Ya existe un jugador con ese nombre",
"maxPlayersReached": "Máximo 20 jugadores",
"minPlayersRequired": "Se necesitan al menos 3 jugadores",
"configuration": "Configuración",
"impostors": "🎭 Impostores",
"impostorClue": "🔍 Pista para impostor",
@@ -50,15 +46,15 @@
"twoMin": "2 min",
"threeMin": "3 min",
"fiveMin": "5 min",
"startGame": "Iniciar partida",
"seeYourWord": "Ver tu palabra",
"eachPlayerMustSee": "Cada jugador debe ver su palabra en secreto",
"roundNumber": "Ronda {round}",
"@roundNumber": {
"placeholders": {
"round": {"type": "int"}
"round": {
"type": "int"
}
}
},
"alreadySeen": "Ya ha visto su palabra",
@@ -67,16 +63,19 @@
"playersRemaining": "Faltan {count} jugadores",
"@playersRemaining": {
"placeholders": {
"count": {"type": "int"}
"count": {
"type": "int"
}
}
},
"youAreImpostor": "¡Eres el impostor!",
"yourWordIs": "Tu palabra es:",
"clueCategory": "Pista: {category}",
"@clueCategory": {
"placeholders": {
"category": {"type": "String"}
"category": {
"type": "String"
}
}
},
"holdToSeeWord": "Mantén pulsado para ver tu palabra",
@@ -84,11 +83,12 @@
"showingWord": "👁️ Mostrando...",
"holdToSee": "👆 Mantén pulsado para ver",
"seenMyWord": "He visto mi palabra",
"debateRound": "Debate - Ronda {round}",
"@debateRound": {
"placeholders": {
"round": {"type": "int"}
"round": {
"type": "int"
}
}
},
"timeUp": "⏰ ¡Tiempo agotado!",
@@ -97,21 +97,28 @@
"activePlayersInfo": "{active} activos • {impostors} impostor(es) ocultos",
"@activePlayersInfo": {
"placeholders": {
"active": {"type": "int"},
"impostors": {"type": "int"}
"active": {
"type": "int"
},
"impostors": {
"type": "int"
}
}
},
"eliminated": "Eliminado",
"notes": "Notas",
"goToVoting": "Ir a votación",
"voting": "🗳️ Votación",
"turnToVote": "Turno de votar:",
"votesProgress": "Votos: {current}/{total}",
"@votesProgress": {
"placeholders": {
"current": {"type": "int"},
"total": {"type": "int"}
"current": {
"type": "int"
},
"total": {
"type": "int"
}
}
},
"whoIsImpostor": "¿Quién crees que es el impostor?",
@@ -120,7 +127,6 @@
"allVoted": "¡Todos han votado!",
"tapToReveal": "Pulsa para revelar el resultado",
"revealResult": "Revelar resultado",
"result": "Resultado",
"revealing": "Revelando...",
"wasImpostor": "¡Era IMPOSTOR! 🎉",
@@ -129,7 +135,6 @@
"seeEndResult": "Ver resultado final",
"impostorGuessWord": "¿El impostor adivina la palabra?",
"nextRound": "Siguiente ronda",
"impostorGuessTitle": "🎯 Adivinanza del impostor",
"impostorCanGuess": "El impostor eliminado puede\nintentar adivinar la palabra",
"ifCorrectImpostorsWin": "Si acierta, ¡los impostores ganan!",
@@ -140,20 +145,23 @@
"theWordWas": "La palabra era: {word}",
"@theWordWas": {
"placeholders": {
"word": {"type": "String"}
"word": {
"type": "String"
}
}
},
"impostorsWin": "¡Los impostores ganan!",
"wrongGuess": "¡No ha acertado!",
"gameContinues": "La partida continúa...",
"gameOver": "Fin de partida",
"playersWin": "¡Los jugadores ganan!",
"theSecretWordWas": "🔍 La palabra era:",
"categoryLabel": "Categoría: {category}",
"@categoryLabel": {
"placeholders": {
"category": {"type": "String"}
"category": {
"type": "String"
}
}
},
"theImpostorWas": "🎭 El impostor era:",
@@ -162,13 +170,16 @@
"roundElimination": "Ronda {round}: {name}",
"@roundElimination": {
"placeholders": {
"round": {"type": "int"},
"name": {"type": "String"}
"round": {
"type": "int"
},
"name": {
"type": "String"
}
}
},
"rematch": "Revancha",
"mainMenu": "Menú principal",
"notesTitle": "📝 Notas",
"notesSaved": "Notas guardadas",
"whoAreYou": "¿Quién eres?",
@@ -176,14 +187,15 @@
"notesOf": "Notas de {name}",
"@notesOf": {
"placeholders": {
"name": {"type": "String"}
"name": {
"type": "String"
}
}
},
"notesAboutPlayers": "Apuntes sobre cada jugador",
"playerNoteHint": "¿Qué ha dicho? ¿Sospechoso?",
"freeNote": "Nota libre",
"freeNoteHint": "Apuntes personales...",
"rulesTitle": "📖 Cómo jugar",
"rulesWhatIsTitle": "🎭 ¿Qué es Farolero?",
"rulesWhatIsBody": "Un juego de deducción social para 3-20 jugadores. Todos reciben una palabra secreta... ¡excepto el impostor! Tu misión: descubrir quién finge.",
@@ -199,20 +211,17 @@
"rulesModesBody": "• Un solo móvil: todos comparten el dispositivo. Cada jugador ve su palabra pulsando y manteniendo un botón.\n\n• Multimóvil: cada jugador usa su propio dispositivo. Se conectan por Bluetooth/WiFi Direct sin necesidad de internet.",
"rulesExampleTitle": "✏️ Ejemplo de partida",
"rulesExampleBody": "Palabra secreta: \"Pizza\"\n\n• Ana: \"Se come caliente\" ✓\n• Carlos: \"Viene en una caja\" ✓\n• Eva (impostor): \"Es muy popular\" 🤔\n• David: \"Tiene queso\" ✓\n\nEva dio una respuesta muy genérica... ¡Sospechosa!",
"joinGameTitle": "Unirse a partida",
"multiDeviceMode": "Modo multimóvil",
"scanQrDescription": "Escanea el código QR que muestra el host para conectarte a la partida vía Bluetooth/WiFi Direct.",
"comingSoon": "Próximamente",
"nearbyNotAvailable": "La conexión multimóvil con Nearby Connections requiere dispositivos Android físicos.\n\nPor ahora, usa el modo \"Un solo móvil\" para jugar en un dispositivo compartido.",
"back": "Volver",
"yes": "Sí",
"no": "No",
"cancel": "Cancelar",
"accept": "Aceptar",
"next": "Siguiente",
"settingsTitle": "Ajustes",
"language": "Idioma",
"soundVolume": "Volumen de efectos",
@@ -220,5 +229,25 @@
"about": "Acerca de",
"version": "Versión",
"developer": "Desarrollador",
"licenses": "Licencias"
}
"licenses": "Licencias",
"scanToJoin": "Escanea el QR para unirte",
"connectedPlayers": "Jugadores conectados",
"waitingForPlayers": "Esperando jugadores...",
"needMorePlayers": "Faltan {count} jugadores más",
"@needMorePlayers": {
"placeholders": {
"count": {
"type": "int"
}
}
},
"starting": "Iniciando...",
"enterNameAndScan": "Escribe tu nombre y escanea el QR del host",
"yourName": "Tu nombre",
"nameRequired": "Escribe tu nombre",
"connectingTo": "Conectando a",
"scanQR": "Escanear QR",
"scanHostQR": "Apunta al QR del host",
"connectedWaiting": "¡Conectado!",
"waitingForHost": "Esperando a que el host inicie la partida..."
}