Здесь находится детальное описание реализации системы спрайтов-анимаций-эффектов.  
Вам вряд ли это понадобится, если вы не собираетесь делать новые эффекты (совсем новые, а не `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`).

Под "старым" понимаются такие изображения, которые были до вызова текущей команды, например:
```renpy
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](./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](./ScreenLang).

***

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