Технические подробности ВН спрайтов - TrueCat17/Ren-Engine GitHub Wiki

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

⚠️ **GitHub.com Fallback** ⚠️