NES TDD

305. Поддержка отражения при отрисовке спрайта

Добавить поддержку горизонтального и вертикального отражения в отрисовку одного спрайта.

Урок 305 из 356 · tests/chapter_09_sprite_rendering/test_305_sprite_render_flip_support.py

Изменяемый файл

emulator/rendering/sprite_renderer.py

Зачем нужен этот шаг

Атрибуты спрайтов уже декодируют биты горизонтального и вертикального отражения. Теперь отрисовщик одного спрайта должен использовать эти биты при выборе пикселя CHR для отрисовки.

Биты отражения в атрибутах спрайта

bit 6: horizontal flip
bit 7: vertical flip

Важная модель

Отражение зеркально отображает изображение внутри области 8x8 спрайта. Оно не перемещает экранную позицию спрайта.

Предлагаемый пример реализации внутри render_sprite_8x8_to_framebuffer():

for tile_y in range(8):
    for tile_x in range(8):
        source_x = 7 - tile_x if attributes.flip_horizontal else tile_x
        source_y = 7 - tile_y if attributes.flip_vertical else tile_y

        color_index = color_indexes[source_y][source_x]

        if color_index == 0:
            continue

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

        ...

Минимальный пример

original row:          1 2 3 . . . . .
horizontal flip row:   . . . . . 3 2 1

Распространённое заблуждение

"Horizontal flip should change sprite.x."

Нет. Целевая область остаётся на позиции sprite.x/sprite.y. Зеркально отображается только выбор исходного пикселя.

Вне рамок этого шага

  • отрисовка всех 64 спрайтов
  • приоритет спрайтов позади фона
  • попадание спрайта 0
  • переполнение спрайтов
  • pygame

Запустить этот урок

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