v0.2.0: i18n 18 idiomas + pantalla ajustes + bancos multiidioma

Internacionalización completa:
- 18 ficheros .arb: es, en, fr, pt, de, it, ru, ja, ko, zh, zh_TW, ar, hi, tr, pl, nl, ca, eu
- Todos los strings extraídos de todas las pantallas
- Detección automática de idioma del sistema
- Selector manual en pantalla de ajustes

Pantalla de ajustes nueva:
- Selector de idioma con banderas emoji
- Vibración ON/OFF
- Acerca de (versión, desarrollador)

Bancos de palabras multiidioma:
- palabras.json (castellano, 1000 palabras)
- palabras_en.json (inglés, 1000 palabras)
- palabras_fr.json (francés, 1000 palabras)
- Fallback a castellano si no hay banco del idioma

13138 líneas Dart, 39 ficheros, 0 issues en flutter analyze
This commit is contained in:
ShanaiaBot
2026-04-04 01:18:09 +02:00
parent de2c8ffa18
commit 1bca50af1d
56 changed files with 14389 additions and 201 deletions

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:el_impostor/l10n/generated/app_localizations.dart';
import '../tema/tema_app.dart';
class PantallaReglas extends StatelessWidget {
@@ -6,78 +7,22 @@ class PantallaReglas extends StatelessWidget {
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
return Scaffold(
appBar: AppBar(title: const Text('📖 Cómo jugar')),
appBar: AppBar(title: Text(l10n.rulesTitle)),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_seccion(
context,
'🎭 ¿Qué es El Impostor?',
'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.',
),
_seccion(
context,
'🔍 ¿Cómo se juega?',
'1. Se reparten los roles: todos reciben la misma palabra, '
'excepto el/los impostores.\n\n'
'2. Debate: por turnos, cada jugador describe la palabra '
'SIN decirla directamente. El impostor debe fingir que la conoce.\n\n'
'3. Votación: al terminar el debate, todos votan a quién '
'creen que es el impostor.\n\n'
'4. Eliminación: el más votado queda eliminado y se revela '
'si era impostor o no.\n\n'
'5. Si era impostor, puede intentar adivinar la palabra. '
'Si acierta, ¡los impostores ganan!',
),
_seccion(
context,
'🏆 ¿Quién gana?',
'• Jugadores: ganan si eliminan a TODOS los impostores.\n'
'• Impostores: ganan si no son descubiertos hasta que '
'queden igual o menos jugadores normales que impostores, '
'o si adivinan la palabra al ser eliminados.',
),
_seccion(
context,
'💡 Consejos para jugadores',
'• Da pistas sutiles que demuestren que conoces la palabra, '
'pero no tan obvias que el impostor las use.\n'
'• Observa quién da respuestas vagas o genéricas.\n'
'• Usa las notas para apuntar lo que dice cada uno.\n'
'• No digas la palabra directamente, ¡eso ayuda al impostor!',
),
_seccion(
context,
'🎭 Consejos para el impostor',
'• Escucha atentamente las pistas de los demás.\n'
'• Intenta deducir la palabra para dar pistas creíbles.\n'
'• No seas el primero en hablar si no estás seguro.\n'
'• Si te dan la categoría como pista, úsala a tu favor.\n'
'• Acusa a otros para desviar la atención.',
),
_seccion(
context,
'📱 Modos de juego',
'• 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.',
),
_ejemplo(
context,
'✏️ Ejemplo de partida',
'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\n'
'Eva dio una respuesta muy genérica... ¡Sospechosa!',
),
_seccion(context, l10n.rulesWhatIsTitle, l10n.rulesWhatIsBody),
_seccion(context, l10n.rulesHowToPlayTitle, l10n.rulesHowToPlayBody),
_seccion(context, l10n.rulesWhoWinsTitle, l10n.rulesWhoWinsBody),
_seccion(context, l10n.rulesTipsPlayersTitle, l10n.rulesTipsPlayersBody),
_seccion(context, l10n.rulesTipsImpostorTitle, l10n.rulesTipsImpostorBody),
_seccion(context, l10n.rulesModesTitle, l10n.rulesModesBody),
_ejemplo(context, l10n.rulesExampleTitle, l10n.rulesExampleBody),
const SizedBox(height: 32),
],
),