Тема 2 из 6

Сцена и Entity

Ursina — простой движок для 3D-игр на Python. Под капотом у него Panda3D — серьёзный движок, на котором делали коммерческие игры, — а сверху удобный интерфейс: куб на экране — это одна строка кода.

В курсе вы по частям соберёте мини-игру от первого лица: сцена, движение, камера, столкновения и сбор предметов на время. Задачи по-прежнему «почини код»: готовая игра, в которой сломан небольшой участок.

Минимальная сцена

from ursina import *

app = Ursina()                                    # окно и движок

ground = Entity(model="plane", scale=20, color=color.green)
cube = Entity(model="cube", texture="white_cube", color=color.orange, position=(0, 0.5, 0))

EditorCamera()                                    # крутить сцену правой кнопкой мыши
app.run()

Всё в сцене — Entity: кубы, пол, игрок, камера, даже надписи. У Entity есть:

  • model — форма: "cube", "sphere", "plane", "quad" или файл модели;
  • color — color.red, color.azure, color.hsv(30, 0.7, 0.9)…; texture — "white_cube", "grass", "brick" или картинка;
  • position — центр объекта (x, y, z); по отдельности x, y, z;
  • scale — размер: одно число или (sx, sy, sz); по отдельности scale_x, scale_y, scale_z;
  • rotation — повороты в градусах вокруг осей: rotation_y — поворот «налево-направо».

Оси

  • x — вправо, y — вверх, z — вперёд, вглубь экрана;
  • пол — плоскость x–z, высота — y.

Куб model="cube" единичного размера занимает от -0.5 до 0.5 по каждой оси вокруг своего центра. Чтобы куб высотой h стоял на полу, его y должен быть h / 2.

Родители и дети

Entity можно сделать дочерним: Entity(parent=table, ...). Тогда он двигается, поворачивается и масштабируется вместе с родителем, а его position и scale считаются в единицах родителя:

table = Entity(model="cube", position=(2, 1, 0), scale=(4, 2, 4))
cup = Entity(parent=table, model="sphere", y=0.5)   # 0.5 «высоты стола» над его центром — верхняя грань
print(cup.world_position)                            # Vec3(2, 2, 0) — где чашка в мире
  • position, scale — относительно родителя;
  • world_position, world_scale — в мире; их можно и присваивать.

Родитель занимает в своих единицах от -0.5 до 0.5 по каждой оси — где бы он ни стоял и какого бы ни был размера. Поэтому «верх стола» — это всегда y = 0.5.

Импорт

В примерах Ursina обычно пишут from ursina import *. Учтите, что так подменяется встроенная функция sum — у Ursina своя, с одним аргументом. В программах курса импортируется только нужное: from ursina import Entity, Vec3.

Как проверяются задачи

Окно и app.run() — под if __name__ == "__main__":. При «Отправить» проверка создаёт Entity без окна и вызывает ваши функции — Ursina это умеет.

Итог

  • app = Ursina(), Entity(model=..., color=..., position=..., scale=...), app.run();
  • x — вправо, y — вверх, z — вперёд; position — центр;
  • parent: координаты ребёнка — в единицах родителя, родитель — от -0.5 до 0.5; world_position;
  • EditorCamera() — осмотреть сцену мышью.