312. La prioridad de sprites usa la máscara de opacidad del fondo

Usa la máscara de opacidad del fondo para aplicar el bit 5 de prioridad de sprites.

Lección 312 de 356 · tests/chapter_09_sprite_rendering/test_312_sprite_priority_uses_background_opaque_mask.py

Archivo a actualizar

emulator/rendering/sprite_renderer.py

Por qué existe este paso

El paso 310 construyó una máscara de opacidad de fondo por píxel. El paso 311 propagó esa máscara a través de la canalización de renderizado de sprites. Este paso finalmente usa la máscara en el renderizador de un solo sprite.

Regla

If a sprite pixel is non-transparent,
and the sprite has priority bit 5 set,
and the background mask says that screen pixel is opaque,
then keep the background pixel and skip drawing the sprite pixel.

Orden importante

1. sprite CHR color index 0 -> skip
2. offscreen pixel -> skip
3. behind-background sprite over opaque background -> skip
4. otherwise draw sprite pixel

Fragmento de implementación de ejemplo

def render_sprite_8x8_to_framebuffer (...) -> ...

...
... 

screen_x = sprite.x + tile_x
screen_y = sprite.y + tile_y

if not (0 <= screen_x < framebuffer.width):
    continue
if not (0 <= screen_y < framebuffer.height):
    continue

# --- ADD THIS NEW BLOCK ---
if (
    background_opaque_mask is not None
    and attributes.is_behind_background
    and background_opaque_mask[screen_y * framebuffer.width + screen_x]
):
    continue
# --- END NEW BLOCK ---

framebuffer.set_pixel(...)

¿Por qué después del recorte? El índice de la máscara usa coordenadas de pantalla. Si indexas la máscara antes de comprobar que el píxel está en pantalla, los sprites fuera de pantalla pueden leer la entrada de máscara equivocada o lanzar un IndexError.

Fuera de alcance

  • construir la máscara dentro de Console.render_framebuffer()
  • seleccionar la tabla de patrones de fondo a partir del bit 4 de PPUCTRL
  • sprite 0 hit
  • desbordamiento de sprites
  • pygame

Ejecutar esta lección

uv run pytest tests/chapter_09_sprite_rendering/test_312_sprite_priority_uses_background_opaque_mask.py -v