Este tutorial adapta pedagógicamente el Día 95. La sección 📝 Contenido original del curso proviene del único archivo de la carpeta:
dia95-tarea14.md(enunciado y pregunta de reflexión, en inglés; aquí traducido). El curso no ofrece guía ni solución, y este tutorial no entrega el juego terminado. Todo lo que no está en ese archivo (especificación, movimiento de la flota como unidad, proyectiles, barreras con "vida", organización con clases, retos 🟢🟡🟠🔴, proyecto extra y la etapa 14 de Mi Portafolio Profesional) es creación de esta adaptación.
Nota sobre las verificaciones: el 28 de septiembre de 2026, con Python 3.14, se ejecutaron las funciones puras de las secciones 4 y 5: una flota de 5 alienígenas entre x = −100 y x = 100 avanza 18 pasos a la derecha, en el paso 19 baja 20 píxeles y cambia de dirección; una versión con error en la que cada alienígena revisa su propio borde rompe la formación (
[(280, 180), (240, 200)]). La parte gráfica conturtlese describe a partir de los Días 20–23 y no se ejecutó en pantalla.
Tabla de contenidos
- La tarea: Space Invaders
- Especificar antes de programar
- 📖 Organizar el juego con clases (lo que ya sabes)
- 📖 La flota se mueve como un solo bloque
- 📖 Disparos, impactos y barreras
- 🚀 Proyecto del día: construcción por versiones
- 🌟 Proyecto extra: Defensores del páramo
- 🏗️ Mi Portafolio Profesional — Etapa 14
- 🧩 Comprueba lo aprendido
- 🤖 Programar con apoyo de IA
- 🛠️ Observaciones sobre el material original
- 📋 Matriz de trazabilidad
- 📦 Evidencias de aprendizaje del Día 95
1. La tarea: Space Invaders
(Fuente: dia95-tarea14.md)
📝 Contenido original del curso
Usando Python Turtle, construye el clásico juego de disparos Space Invaders. (El enunciado enlaza la página de Wikipedia del juego.)
Tu nave espacial puede moverse a la izquierda y a la derecha y puede disparar a algunas naves alienígenas. Cada segundo, los alienígenas se acercan a tu nave. Cuando los alienígenas tocan tu nave, se acaba el juego (game over). Normalmente hay algunas barreras entre tú y los alienígenas que te ofrecen posiciones defensivas.
Puedes jugarlo en elgoog.im/space-invaders.
Pregunta de la tarea — Momento de reflexión: cómo abordaste el proyecto; qué fue difícil y qué fácil; cómo mejorarías; tu mayor aprendizaje; qué harías distinto.
Prerequisitos:
turtle, eventos de teclado ytracer/update(Días 18–20); herencia (Día 21); Pong, Turtle Crossing y Breakout (Días 22, 23 y 87); listas y comprensión de listas (Días 4 y 26).
2. Especificar antes de programar
(Sección creada para esta adaptación, aplicando el método que el curso pidió en el Día 87.)
🔍 Antes de programar
Juega 5 minutos y escribe la especificación. Ejemplo (el tuyo puede ser distinto):
OBJETOS: Nave, Alien (muchos, en formación), Bala (de la nave), Bala enemiga,
Barrera (varios bloques), Marcador
REGLAS:
- La nave se mueve ← → sin salir de la pantalla y dispara con espacio.
- Solo una bala de la nave en pantalla a la vez (como en el original).
- La flota se mueve de lado a lado; al tocar un borde, TODA baja y cambia de dirección.
- Bala que toca un alien: ambos desaparecen, suma puntos.
- Los aliens disparan al azar hacia abajo.
- Bala (de cualquiera) que toca una barrera: la barrera pierde un "trozo".
- Game over si una bala enemiga toca la nave (y se acaban las vidas)
o si un alien llega a la altura de la nave.
- Victoria (o siguiente nivel) si no quedan aliens.Lista de tareas sugerida: ventana y ciclo → nave → disparo → flota estática → flota en movimiento → impactos → disparos enemigos → barreras → vidas y marcador → fin del juego.
💡 Compara con el Breakout (Día 87): la bala es como la pelota (pero va en línea recta y desaparece); los alienígenas son como los ladrillos (pero se mueven). Reutiliza lo que puedas.
3. 📖 Organizar el juego con clases (lo que ya sabes)
(Sección creada para esta adaptación.)
| Clase | Hereda de | Responsabilidad |
|---|---|---|
Nave |
Turtle |
Moverse con límites, crear balas |
Bala |
Turtle |
Avanzar en línea recta; saber si salió de la pantalla |
Alien |
Turtle |
Su forma, color y puntos |
Flota |
— (contiene una lista de Alien) |
Moverse como bloque, elegir quién dispara, saber si quedan aliens |
Barrera |
— (lista de bloques pequeños) | Perder bloques al recibir impactos |
Marcador |
Turtle |
Puntos, vidas, mensajes |
Una idea importante: Flota no hereda de Turtle, sino que contiene muchos. Eso se llama composición ("una flota tiene aliens") y es distinto de la herencia ("un alien es una tortuga"). Pregúntate con cada clase: ¿"es un" o "tiene un"?
Formas personalizadas: turtle permite registrar una imagen .gif como forma (screen.addshape("alien.gif") y alien.shape("alien.gif")). Las imágenes GIF no rotan con la tortuga, lo que aquí no importa. Usa imágenes propias o con licencia libre.
4. 📖 La flota se mueve como un solo bloque
(Sección creada para esta adaptación. Función verificada.)
🎯 Objetivo de aprendizaje
Mover un grupo de objetos de forma coordinada, tomando decisiones sobre el grupo, no sobre cada objeto por separado.
📖 Explicación conceptual
Si cada alienígena revisara su propio borde, el de la derecha bajaría y los demás seguirían avanzando: la formación se deshace. Verificado con una versión con error: dos aliens en x = 280 y x = 230 terminan en [(280, 180), (240, 200)], a alturas distintas.
La decisión correcta se toma para toda la flota: si el alien que está más a la derecha (o más a la izquierda) va a salirse, todos bajan y todos cambian de dirección.
🔎 Ejemplo explicado
BORDE = 280
def mover_flota(posiciones, direccion, paso=10, bajada=20):
if not posiciones:
return posiciones, direccion
xs = [x for x, _ in posiciones]
if max(xs) + paso * direccion > BORDE or min(xs) + paso * direccion < -BORDE:
return [(x, y - bajada) for x, y in posiciones], -direccion
return [(x + paso * direccion, y) for x, y in posiciones], direccion- Trabaja con tuplas de posiciones, no con tortugas: se prueba sin ventana. En el juego, aplicarías las nuevas posiciones con
alien.goto(x, y). direcciones1(derecha) o-1(izquierda): multiplicar por ella evita escribir dos casos.- Se revisa la próxima posición (
max(xs) + paso * direccion) para no salirse ni un paso. if not posicionesevita el error demax()con una lista vacía (cuando no quedan aliens).
Verificado: 5 aliens entre −100 y 100 avanzan 18 pasos; en el paso 19 bajan de y = 200 a y = 180 y la dirección pasa a −1; en el siguiente paso el de la derecha va de 280 a 270.
¿"Cada segundo"?
El enunciado dice que los aliens se acercan cada segundo, pero el ciclo del juego se repite muchas veces por segundo (para que la nave y las balas se muevan suave). Solución: mover la flota solo cada cierto número de cuadros, o con un temporizador aparte (screen.ontimer(mover, 1000)). En el original, la flota acelera a medida que quedan menos aliens: ¿cómo lo harías?
5. 📖 Disparos, impactos y barreras
(Sección creada para esta adaptación.)
Balas
- Una bala a la vez: si ya hay una bala de la nave en pantalla, la barra espaciadora no hace nada. Esto hace el juego más estratégico y simplifica el código.
- Balas que salen de la pantalla: ocúltalas y quítalas de la lista (o reutilízalas). Si solo las ocultas, la lista crece sin fin y el juego se vuelve lento.
Impactos
Usa la idea de colisión rectangular del Breakout (Día 87): comparar la distancia en cada eje con la suma de los "medios tamaños". Y aplica la regla de oro: no eliminar de una lista mientras la recorres; recorre una copia o marca los eliminados y bórralos después.
Barreras con "vida"
Dos enfoques:
| Enfoque | Cómo | Ventaja | Desventaja |
|---|---|---|---|
| Barrera con contador | Un solo objeto con vida = 5; cambia de color al recibir impactos |
Simple | No se ve el "hueco" del impacto |
| Barrera de bloques | Muchos cuadritos pequeños; cada impacto borra uno | Se parece al original | Muchas colisiones que revisar (más lento) |
Alcanzar la nave
def alcanzo_nave(posiciones, y_nave=-250, margen=20):
return any(y <= y_nave + margen for _, y in posiciones)any(...) devuelve True si al menos un alien cumple la condición (verificado: un alien en y = −240 → True; en y = 0 → False).
⚠️ Errores frecuentes
| Error | Qué ocurre | Solución |
|---|---|---|
| Cada alien revisa su borde | La formación se deshace | Decisión sobre el grupo (sección 4) |
max() de una lista vacía |
ValueError al matar al último alien |
Comprueba si quedan aliens |
| Balas infinitas | El juego se vuelve lento | Límite de balas y eliminar las que salen |
| Una bala destruye varios aliens | Atraviesa la fila | Al primer impacto, la bala desaparece (break) |
| La flota se mueve demasiado rápido | Se mueve en cada cuadro | Contador de cuadros o ontimer |
screen.onkey sin screen.listen() |
Las teclas no responden | screen.listen() antes del ciclo |
6. 🚀 Proyecto del día: construcción por versiones
(Desarrolla la tarea dia95-tarea14.md. Las versiones siguen la lista de tareas de la sección 2.)
Problema
Construir Space Invaders con Python turtle.
Contexto
Continúa la "semana de juegos clásicos" (Día 87): cada grupo presenta un segundo juego, esta vez con muchos objetos en movimiento.
Objetivo
Un Space Invaders jugable, con flota en formación, disparos de ambos lados, barreras, vidas y marcador.
Requisitos funcionales
- Nave que se mueve ← → con límites y dispara con espacio.
- Flota de al menos 3 filas × 8 columnas que se mueve en bloque y baja al tocar un borde.
- Impactos de balas en aliens (con puntos) y en barreras.
- Game over si los aliens alcanzan la nave o si se acaban las vidas; victoria si no quedan aliens.
Restricciones técnicas
- Clases en archivos separados (
nave.py,flota.py,barrera.py,marcador.py). - Movimiento de la flota y colisiones en funciones puras probadas.
- Sin copiar un tutorial de Space Invaders (mismo principio del Día 87).
Planificación
La especificación de la sección 2 es tu plan. Añade: probar cada tarea antes de marcarla; corregir; mejorar con los retos.
Construcción paso a paso
- Versión 1 — Nave: ventana, ciclo y nave con límites.
- Versión 2 — Disparo: una bala a la vez, que desaparece al salir.
- Versión 3 — Flota: formación estática; luego, movimiento en bloque.
- Versión 4 — Impactos: balas contra aliens, puntos.
- Versión 5 — Contraataque: disparos enemigos al azar (
random.choicede los aliens de la fila inferior de cada columna), vidas. - Versión 6 — Barreras.
- Versión final: fin del juego, reinicio,
README.mdcon GIF y diario.
Pruebas
| # | Caso | Resultado esperado |
|---|---|---|
| 1 | mover_flota con 5 aliens desde −100…100 hacia la derecha |
18 pasos a la derecha; en el 19, bajan 20 y cambia la dirección |
| 2 | mover_flota([], 1) |
([], 1) sin error |
| 3 | alcanzo_nave([(0, -240)]) |
True |
| 4 | Pulsar espacio 10 veces rápido | Solo una bala en pantalla |
| 5 | Matar al último alien | Victoria, sin errores |
| 6 | Barrera que recibe 5 impactos (o todos sus bloques) | Desaparece |
| 7 | Jugar 3 minutos | El juego no se vuelve más lento con el tiempo |
🧪 Prueba y depuración
for alien in aliens:
if alien.xcor() > 280 or alien.xcor() < -280:
direccion *= -1
alien.sety(alien.ycor() - 20)
alien.setx(alien.xcor() + 10 * direccion)Encuentra tres problemas: solo baja el alien que tocó el borde (la formación se rompe); la dirección puede cambiar varias veces en la misma vuelta si varios aliens están en el borde; y los aliens ya recorridos se movieron con la dirección anterior.
⭐ Extensión del proyecto
- 🟢 Reto 1 — Aplicación: la flota acelera a medida que quedan menos aliens.
- 🟡 Reto 2 — Ampliación: la nave misteriosa (OVNI) que cruza la parte superior de vez en cuando y da puntos al azar.
- 🟠 Reto 3 — Desafío: barreras de bloques que se "desmoronan" de forma realista (el bloque golpeado y, a veces, un vecino).
- 🔴 Reto 4 — Pensamiento computacional: niveles con formaciones distintas leídas desde archivos de texto, y una dificultad que se ajusta al jugador (si pierde rápido, el siguiente intento es un poco más fácil). Diseña la regla de ajuste y justifica por qué es justa.
7. 🌟 Proyecto extra: Defensores del páramo
(Proyecto creado para esta adaptación; no existe en el curso original.)
Situación
Los páramos colombianos producen buena parte del agua que llega a muchas ciudades. El grupo ecológico quiere un juego que muestre sus amenazas: desde arriba descienden "amenazas" (incendios, basura, ganadería no controlada, minería ilegal) hacia los frailejones de la parte inferior.
Requisitos
- Reutiliza la estructura de tu Space Invaders: las amenazas bajan en formación.
- El jugador elige la "herramienta" adecuada para cada amenaza (por ejemplo, 1 = agua, 2 = recolección, 3 = vigilancia), con disparos de color distinto; solo la correcta elimina la amenaza.
- Al final, una pantalla con un dato real sobre cada amenaza, con su fuente (investiga en fuentes confiables).
Decisiones que debes tomar (y justificar)
- ¿Cómo muestras qué herramienta sirve para qué amenaza sin que el juego sea solo adivinar?
- ¿Cómo evitas que el juego trivialice un problema serio?
Casos de prueba
- Herramienta incorrecta: la amenaza sigue.
- Un frailejón alcanzado desaparece; si se pierden todos, el juego termina.
8. 🏗️ Mi Portafolio Profesional — Etapa 14
(Proyecto integrador creado para esta adaptación; etapas anteriores en los Días 82 a 94.)
Etapa 14 (hoy):
- Repositorio con
PLAN.md(especificación y lista de tareas), las clases, las pruebas de las funciones puras y un GIF. - En el
README.md, un diagrama simple de las clases con sus relaciones "es un" / "tiene un". DIARIO.mddel Día 95 y ficha enproyectos.json.- Comparación: en tu diario, compara el Breakout (Día 87) con este juego. ¿Qué código reutilizaste? ¿Qué hiciste mejor esta vez?
9. 🧩 Comprueba lo aprendido
Conceptuales
- ¿Qué diferencia hay entre herencia y composición? Da un ejemplo de cada una en este juego.
- ¿Por qué la decisión de bajar debe tomarse para toda la flota?
- ¿Por qué hay que eliminar de la lista las balas que salen de la pantalla?
- ¿Qué hace
any()?
Análisis de código
xs = [x for x, _ in posiciones]¿Qué contiene xs? ¿Qué significa el _?
Predicción
Con BORDE = 280, una flota cuyo alien más a la derecha está en x = 275 y direccion = 1, paso = 10: ¿qué hace mover_flota?
Depuración
"Cuando elimino al último alien, el juego se cierra con ValueError: max() arg is an empty sequence." ¿Dónde y cómo lo corriges?
Modificación
Cambia mover_flota para que el paso aumente cuando quedan menos de 10 aliens.
Creación
Escribe aliens_que_pueden_disparar(posiciones) que devuelva, para cada columna (misma x), solo el alien de más abajo.
10. 🤖 Programar con apoyo de IA
Ciclo de trabajo: formula el problema → inténtalo tú primero → consulta a la IA sobre un punto concreto → lee y entiende → prueba → compara con la documentación oficial → modifica → explica con tus palabras.
Actividad 1 — Conceptos, no juegos. Pregunta a una IA "¿cuál es la diferencia entre herencia y composición en programación orientada a objetos?". Aplica la explicación a tus clases y justifica cada relación.
Actividad 2 — Revisión de rendimiento. Si tu juego se vuelve lento, describe (sin pegar todo el código) cuántos objetos hay y cómo revisas colisiones. Pide ideas y mide con time.perf_counter() si mejoran.
Actividad 3 — Documentación. Pregunta cómo usar imágenes GIF como formas en turtle. Comprueba en la documentación oficial (register_shape/addshape) qué formatos admite.
Declara el uso: sección "Uso de IA" en el README.md.
11. 🛠️ Observaciones sobre el material original
| Archivo | Observación | Tratamiento |
|---|---|---|
dia95-tarea14.md |
"Cada segundo los aliens se acercan" no encaja con un ciclo de muchos cuadros por segundo | Sección 4: contador de cuadros u ontimer |
dia95-tarea14.md |
No menciona que la flota debe moverse como bloque | Sección 4, con el error verificado |
dia95-tarea14.md |
Las barreras son opcionales ("usually") | Versión 6 y reto 3 |
dia95-tarea14.md |
Enlaza una versión jugable en un sitio espejo (elgoog.im) | Se conserva como referencia |
12. 📋 Matriz de trazabilidad
| Contenido original | Archivo de origen | Concepto desarrollado | Ejercicio original | Reto adicional | Proyecto relacionado |
|---|---|---|---|---|---|
| Space Invaders con Python Turtle | dia95-tarea14.md |
Secciones 2 y 3 | Juego Space Invaders | Retos 2 y 4 | Secciones 6 y 8 |
| Nave que se mueve a los lados y dispara | dia95-tarea14.md |
Sección 5 | Juego Space Invaders | — | Sección 6 |
| Aliens que se acercan cada segundo; game over al tocar la nave | dia95-tarea14.md |
Secciones 4 y 5 | Juego Space Invaders | Reto 1 | Sección 6 |
| Barreras defensivas | dia95-tarea14.md |
Sección 5 | Juego Space Invaders | Reto 3 | Sección 6 |
| Momento de reflexión | dia95-tarea14.md |
Sección 6 (versión final) | Pregunta de reflexión | — | Sección 8 |
| (No existe en el curso original) | — | Composición, movimiento en bloque | — | Defensores del páramo | Sección 7 |
13. 📦 Evidencias de aprendizaje del Día 95
PLAN.mdcon la especificación y la lista de tareas.- El juego funcionando (GIF o video con victoria y game over).
- Pruebas de
mover_flota, colisiones yalcanzo_nave. - Diagrama de clases y comparación con el Breakout.
DIARIO.mddel Día 95 y ficha en el portafolio.- Cuaderno de errores: formación que se deshace,
max()de lista vacía, balas infinitas, bala que atraviesa varios aliens, flota demasiado rápida, teclas sinlisten().