Здесь находится детальное описание реализации системы спрайтов-анимаций-эффектов.
Вам вряд ли это понадобится, если вы не собираетесь делать новые эффекты (совсем новые, а не `fade4 = Fade(4.0)`).

Хотя можете и посмотреть, если интересно. Но, вероятно, в происходящем здесь будет сложно разобраться неподготовленным и/или немотивированным людям.
Вас предупреждали.

Итак, поехали! Далее идёт описание того, что происходит в файлах `Ren-Engine/rpy/sprite*.rpy` (имеются ввиду несколько файлов) и `Ren-Engine/rpy/screens/sprites.rpy`.
В последнем содержатся функции `set_scene`, `show_sprite` и `hide_sprite`, а так же происходит отрисовка изображений в окно игры с помощью ScreenLang.
Также эффекты можно найти в `Ren-Engine/rpy/sprite_effects/*.rpy`.

## Спрайт

Есть такое понятие как спрайт (класс `Sprite`). Именно такими объектами оперируют команды `scene`, `show` и `hide`.

Его отличие от изображения (класс `SpriteAnimationData`) в том, что он может содержать в себе несколько изображений: новое (`new_data`) и старое (`old_data`).

Под "старым" понимаются такие изображения, которые были до вызова текущей команды, например:

    show np normal with dissolve
    # Тут есть только новое (np normal), старое - пустое (None).

    show np smile with dspr
    # А тут уже оба: новое (np smile) и старое (np normal).

Так вот, спрайты содержат в себе:

- Список данных к отображению (свойство `data_list`):
  - Содержит как минимум `new_data` и/или `old_data` - любое может быть пустым,
  - Элементы списка - `SpriteAnimationData` - содержат в себе:
    - Свойства (`xpos`, `ypos`, `xsize`...),
    - Анимации (класс `SpriteAnimation`),
- Эффект (мб и `None`, если он отсутствует).

Спрайты обновляются перед каждым кадром:

1. При этом обновляются его данные (по порядку в `data_list`):
   - Которые также обновляют свои анимации,
2. Эффект (если есть),
3. Вложенные спрайты (в `contains` данных, если есть).

## Анимации

Важный момент: анимации не содержат в себе изображений, других анимаций, свойств и т. п.
Они просто являются набором действий, не больше.
Анимации сохраняют всё в свою `data`, т. е. все 3 анимации имеют общее "хранилице данных".

## Данные

Каждый экземпляр данных имеет:

- `image` - путь к файлу картинки,
- `contains` - список из "вложенных" спрайтов:
  - Тут нужны именно спрайты, а не данные с анимациями, т. к. в будущем к ним будут применяться эффекты,
- Текущие значения свойств (`xpos`, `ypos`, `xsize`...),
- Анимации (ATL) - `SpriteAnimation`, 3 штуки (`decl_at`, `at`, `show_at` - порядок совпадает с главой про ATL),

Вернёмся к спрайтам.
При вызове команды `show` есть 2 варианта развития событий:

1. Спрайт с таким псевдонимом (обычно 1-е слово в имени) уже есть:
   - Тогда новый спрайт получает в свойство `old_data` то, что у старого в `new_data`.
2. Если же его нет:
   - То свойство `old_data` будет пустым. Потом новый спрайт добавляется в нужное место в список `sprites_list`.

При вызове `hide` ищется спрайт с указанным псевдонимом.

1. Если эффект не указан:
   - Этот спрайт просто удаляется.
2. Если указан:
   1. Создаётся новый спрайт,
   2. Его `old_data` приравнивается к `new_data`, а `new_data` удаляется,
   3. Свойство `hiding` ставится в `True` (признак того, что спрайт исчезает),
   4. При очередном обновлении спрайта эффект завершается, вызывается `remove_effect` (удаление эффекта),
   5. И выясняется, что `hiding == True`, а значит - спрайт удаляется со сцены.

## Отрисовка

Упрощённая версия:

1. Создаётся список для объектов, которые нужно будет отрисовать,
2. Проходимся по каждому спрайту (перед этим вызвав его обновление), в нём - по каждому изображению в `data_list`, у каждого изображения вызываем `get_all_data()`,
3. Эта функция возвращает текущее изображение + все вложенные в `contains` с посчитанными параметрами относительно родительского изображения:
   - Например, если есть изображение с `xpos` 100 и в него вложено ещё одно с `xpos` 50, то она вернёт 2 изображения с `xpos` 100 и 150,
4. Полученные результаты добавляем в список для отрисовки,
5. После того, как всё добавили - отрисовываем каждый элемент списка.

Эта несложная схема нужна, чтобы отрисовать "дерево" спрайтов "линейным" циклом на ScreenLang.

Напоминание:
Примеры реализации эффектов можно найти в `Ren-Engine/rpy/sprite_effects/*.rpy`.