311. Прокидываем маску непрозрачности фона через конвейер спрайтов
Прокидываем маску непрозрачности фона через конвейер рендеринга спрайтов.
Урок 311 из 356 · tests/chapter_09_sprite_rendering/test_311_thread_background_opaque_mask_through_sprite_pipeline.py
Файлы для обновления
emulator/rendering/frame_compositor.py
emulator/rendering/sprite_renderer.pyЗачем нужен этот шаг
Шаг 310 создал BackgroundOpaqueMask. Прежде чем применять поведение приоритета спрайтов, мы сначала делаем так, чтобы соответствующие функции принимали эту маску и передавали её дальше.
Это сохраняет постепенность курса
Step 310 -> build the mask
Step 311 -> thread the mask through function signatures
Step 312 -> use the mask to enforce sprite priority bit 5Требуемая форма API
def composite_background_and_sprites(
background: Framebuffer,
oam: bytes | bytearray,
pattern_table: bytes,
sprite_palettes: SpritePalettes,
# --- ADD THIS NEW LINE ---
background_opaque_mask: BackgroundOpaqueMask | None = None,
) -> Framebuffer:
...
render_oam_sprites_to_framebuffer(
framebuffer,
oam,
pattern_table,
sprite_palettes,
# --- ADD THIS NEW LINE ---
background_opaque_mask,
)
...
def render_oam_sprites_to_framebuffer(
framebuffer: Framebuffer,
oam: bytes | bytearray,
pattern_table: bytes,
sprite_palettes: SpritePalettes,
# --- ADD THIS NEW LINE ---
background_opaque_mask: BackgroundOpaqueMask | None = None,
) -> None:
...
render_sprite_8x8_to_framebuffer(
framebuffer,
sprite,
pattern_table,
sprite_palettes,
# --- ADD THIS NEW LINE ---
background_opaque_mask,
)
def render_sprite_8x8_to_framebuffer(
framebuffer: Framebuffer,
sprite: SpriteEntry,
pattern_table: bytes,
sprite_palettes: SpritePalettes,
# --- ADD THIS NEW LINE ---
background_opaque_mask: BackgroundOpaqueMask | None = None,
) -> None:
...Также добавьте импорт типа там, где это нужно
# --- ADD THIS NEW LINE ---
from emulator.rendering.nametable_renderer import BackgroundOpaqueMaskВажно
На этом шаге маску использовать пока не требуется. Следующий шаг добавит правило:
if sprite is behind background and background_opaque_mask[pixel] is True:
skip drawing this sprite pixelПочему опциональный None? Более старые тесты и более ранние шаги курса уже вызывают эти вспомогательные функции рендеринга без маски фона. Сохранение аргумента опциональным сохраняет обратную совместимость, пока мы развиваем конвейер.
Вне рамок
- применение бита 5 приоритета спрайтов
- изменение Console.render_framebuffer()
- построение маски из состояния PPU
- sprite 0 hit
- переполнение спрайтов
- pygame
Запустить этот урок
uv run pytest tests/chapter_09_sprite_rendering/test_311_thread_background_opaque_mask_through_sprite_pipeline.py -v