286. Bucle principal manual de pygame
Añadir un bucle principal manual de pygame para el ejecutor de comprobación rápida del framebuffer.
Lección 286 de 356 · tests/chapter_05_rendering_pipeline/test_286_manual_pygame_main_loop.py
Archivos a actualizar/crear
tools/show_framebuffer.pyPor qué existe este paso
El paso anterior añadió ayudantes que pueden dibujar un Framebuffer sobre una Surface de pygame. Este paso añade el bucle de ventana manual para que un desarrollador pueda confirmar visualmente que los datos de Framebuffer puros se pueden mostrar.
Importante
Esto es un ejecutor manual de comprobación rápida, no un test de renderizado automatizado. Los tests automatizados no deben abrir una ventana real de pygame.
Ejecuta la herramienta como un módulo de Python
uv run python -m tools.show_framebufferEl flag -m de Python espera un nombre de módulo, no una ruta de archivo. El nombre del módulo usa puntos:
tools.show_framebufferno como una ruta de archivo:
tools/show_framebuffer.pyEl Python moderno admite este diseño de proyecto como paquete de espacio de nombres (namespace package), así que esta lección no requiere un archivo __init__.py.
Comandos manuales
Correct:
uv run python -m tools.show_framebuffer
Incorrect:
uv run python -m tools/show_framebuffer.py
uv run python -m tools.show_framebuffer.py¿Qué es el bucle principal de pygame?
Un bucle principal de pygame mantiene una ventana viva repitiendo
1. reading events
2. drawing to the window surface
3. presenting the drawn imageForma mínima
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
draw_framebuffer(window, framebuffer, SCALE)
pygame.display.flip()¿Qué es pygame.display.flip()? Presenta el contenido actual de la superficie de la ventana en la pantalla. En términos simples:
draw pixels -> flip -> user sees pixelsResultado visual manual esperado
El framebuffer en forma de tablero de ajedrez debería mostrar un patrón blanco/negro u oscuro/blanco como:
+----------------+
| ██ ██ ██ ██ |
| ██ ██ ██ ██ |
| ██ ██ ██ |
| ██ ██ ██ |
| ██ ██ ██ ██ |
| ██ ██ ██ ██ |
+----------------+El tamaño exacto de los bloques depende del tamaño del framebuffer y de SCALE, pero la comprobación visual importante es:
alternating light and dark squares are visible
closing the window exits cleanlyEjemplo de implementación sugerida
SCALE = 3
def main() -> None:
framebuffer = make_checkerboard_framebuffer()
pygame.init()
try:
window = pygame.display.set_mode(
(framebuffer.width * SCALE, framebuffer.height * SCALE)
)
pygame.display.set_caption("Framebuffer Smoke Test")
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
draw_framebuffer(window, framebuffer, SCALE)
pygame.display.flip()
finally:
pygame.quit()
if __name__ == "__main__":
main()Regla de arquitectura
pygame permanece fuera del núcleo del emulador. Este archivo puede importar pygame porque vive bajo tools/. No importes pygame desde emulator/rendering, emulator/ppu ni emulator/console.
Fuera de alcance
- probar la ventana real de pygame en pytest
- cargar ROMs
- renderizar la salida en vivo de Console
- entrada del mando
- sprites
Ejecutar esta lección
uv run pytest tests/chapter_05_rendering_pipeline/test_286_manual_pygame_main_loop.py -v