Files
Ruleta_Actvidad/README.md
T

239 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🎡 Ruleta Interactiva — SCORM 1.2
Actividad e-learning interactiva basada en una ruleta con preguntas de cultura general, construida con React, TypeScript, Tailwind CSS y empaquetada como contenido SCORM 1.2.
---
## 🛠️ Stack Tecnológico
| Tecnología | Versión | Uso |
|---|---|---|
| React | 19 | UI y manejo de estado |
| TypeScript | 5 | Tipado estático |
| Tailwind CSS | 4 | Estilos utilitarios |
| Vite | 6 | Bundler y dev server |
| Howler.js | 2 | Manejo de audio |
| scorm-again | 3 | Simulador SCORM en desarrollo |
---
## 📁 Estructura del Proyecto
```
src/
├── audio/
│ ├── ExtendedHowl.ts # Clase que extiende Howl con eventos de timeupdate (250ms)
│ ├── AudioController.ts # Controlador global de audio + sonidos precargados
│ └── audios.ts # Constantes con rutas de archivos de audio
├── components/
│ ├── ui/
│ │ └── Button.tsx # Botón reutilizable (variantes: primary, secondary, outline, danger)
│ ├── layout/
│ │ ├── Header.tsx # Cabecera de la aplicación
│ │ └── Footer.tsx # Pie de página
│ ├── screens/
│ │ ├── Cover.tsx # Pantalla de portada con introducción y botón comenzar
│ │ ├── Game.tsx # Pantalla principal del juego
│ │ └── Result.tsx # Pantalla de cierre (3 estados)
│ └── game/
│ ├── Ruleta/
│ │ └── RuletaSVG.tsx # Ruleta SVG con 4 secciones de colores
│ ├── QuestionModal.tsx # Modal de pregunta con temporizador y feedback
│ └── ResultModal.tsx # Modal interno (reservado)
├── data/
│ └── preguntas.json # 4 categorías × 8 preguntas + banco genérico
├── hooks/
│ ├── useAudio.ts # Hook para consumir el AudioController
│ ├── useIntentos.ts # Manejo de intentos con persistencia en sessionStorage
│ ├── useRuleta.ts # Lógica completa del juego
│ ├── useSCORM.ts # Hook para inicializar y usar SCORM 1.2
│ └── useScale.ts # Escalado adaptativo 1920×1080
├── layouts/
│ └── MainLayout.tsx # Template principal con escalado adaptativo
├── scorm/
│ └── scorm.ts # Funciones SCORM 1.2 con fallback a sessionStorage
├── types/
│ └── index.ts # Interfaces TypeScript (Pregunta, Categoria, PreguntasData)
├── App.tsx # Manejo de pantallas y flujo de intentos
└── main.tsx # Entry point con simulador SCORM en desarrollo
public/
├── audios/
│ ├── click.mp3 # Sonido de clic en botones
│ ├── wheel-spin.mp3 # Sonido al girar la ruleta
│ ├── feedback-correct.mpeg # Sonido de respuesta correcta
│ └── feedback-incorrect.mpeg # Sonido de respuesta incorrecta
├── img/
│ ├── ruleta.png # Imagen de ruleta (respaldo)
│ └── indicador.png # Imagen de indicador (respaldo)
└── imsmanifest.xml # Manifiesto SCORM 1.2 requerido por el LMS
```
---
## 🎮 Flujo de la Actividad
```
Portada (Cover)
│ clic en "Comenzar" → consume 1 intento + sonido click
Juego (Game)
│ clic en la ruleta → gira + sonido wheel-spin (4s)
Detecta sección (4 categorías × 90°)
Modal de Pregunta (temporizador 30s)
├── Respuesta correcta → sonido correct → feedback → círculo de progreso
├── Respuesta incorrecta → sonido incorrect → feedback → círculo de progreso
└── Tiempo agotado → cuenta como incorrecta → feedback
│ 10 preguntas respondidas
Pantalla de Resultado
├── ≥ 8 correctas → ¡Felicidades! (sin botón)
├── < 8 correctas + intentos disponibles → "Casi" + botón Reintentar
└── Sin intentos → Mensaje final (persiste al recargar)
```
---
## 🎯 Categorías de Preguntas
| # | Categoría | Color | Preguntas |
|---|---|---|---|
| 1 | 🏛️ Historia | Morado `#7C3AED` | 8 |
| 2 | 🌍 Geografía | Verde `#059669` | 8 |
| 3 | 🔬 Ciencia | Rojo `#DC2626` | 8 |
| 4 | 🎨 Arte y Literatura | Naranja `#D97706` | 8 |
> Las preguntas se seleccionan aleatoriamente sin repetir dentro de cada categoría.
> Si se agotan las preguntas de una categoría, se usa el **banco genérico** (5 preguntas).
---
## 🏆 Criterios de Aprobación
| Criterio | Valor |
|---|---|
| Preguntas por actividad | 10 |
| Mínimo para aprobar | 8 correctas |
| Intentos totales | 3 |
| Tiempo por pregunta | 30 segundos |
| Tiempo agotado | Cuenta como incorrecta |
---
## 🔄 Sistema de Intentos
- El intento se consume al hacer clic en **"Comenzar"**
- Se persiste en `sessionStorage`, por lo que recargar la página **no** recupera el intento
- Al agotar los 3 intentos, la pantalla de cierre final persiste aunque se recargue
---
## 📐 Escalado Adaptativo
El hook `useScale` escala toda la actividad a una resolución base de **1920×1080** manteniendo proporciones en cualquier pantalla:
```ts
const BASE_WIDTH = 1920
const BASE_HEIGHT = 1080
const scale = Math.min(window.innerWidth / BASE_WIDTH, window.innerHeight / BASE_HEIGHT)
```
> Solo orientación horizontal. No aplica diseño para pantallas verticales.
---
## 🔊 Audio
Los audios se precargan al iniciar la aplicación mediante `AudioController`:
```ts
sounds.click?.play() // Botones de navegación
sounds.wheelSpin?.play() // Al girar la ruleta
sounds.correct?.play() // Respuesta correcta
sounds.incorrect?.play() // Respuesta incorrecta
```
---
## 📡 SCORM 1.2
El módulo SCORM (`src/scorm/scorm.ts`) implementa todas las funciones estándar con **fallback automático a `sessionStorage`** cuando no hay LMS disponible:
| Función | CMI Key |
|---|---|
| `initSCORM()` | Inicializa y establece status `incomplete` |
| `getStudentName()` | `cmi.core.student_name` |
| `getLessonStatus()` / `setLessonStatus()` | `cmi.core.lesson_status` |
| `getLessonLocation()` / `setLessonLocation()` | `cmi.core.lesson_location` |
| `getScore()` / `setScore()` | `cmi.core.score.raw/max/min` |
| `getSuspendData()` / `setSuspendData()` | `cmi.suspend_data` |
| `getScormData()` / `setScormData()` | Cualquier clave CMI |
| `finishSCORM()` | Calcula `session_time` en HH:MM:SS y cierra |
| `completeLesson()` | Establece status `completed` |
> En desarrollo, `scorm-again` simula el `window.API` del LMS automáticamente.
---
## 🧩 Componente Button
```tsx
<Button variant="primary" size="lg" onClick={fn}>Texto</Button>
<Button variant="secondary" size="md">Texto</Button>
<Button variant="outline" size="sm">Texto</Button>
<Button variant="danger" disabled>Texto</Button>
```
---
## 🚀 Comandos
```bash
# Instalar dependencias
npm install
# Desarrollo
npm run dev
# Build para producción
npm run build
# Verificar TypeScript
npx tsc --noEmit
```
---
## 📦 Empaquetado SCORM
Para publicar en un LMS (Moodle, Cornerstone, etc.):
1. Ejecutar `npm run build`
2. Abrir la carpeta `dist/` — el `imsmanifest.xml` se copia automáticamente
3. Seleccionar **todo** el contenido de `dist/` y comprimir en un `.zip`
4. Subir el `.zip` al LMS como paquete SCORM 1.2
> El `masteryscore` está configurado en **80** en el `imsmanifest.xml`.
---
## 📋 Pendientes
- [ ] Reemplazar categorías y preguntas de cultura general por el contenido real del cliente
- [ ] Integrar `setScore` y `completeLesson` con SCORM al finalizar la actividad
- [ ] Pruebas en LMS real (Moodle)
- [ ] Definir diseño visual final (colores, logo, imágenes del cliente)