Тема 2 из 6

Окно, фигуры и батчи

pyglet — библиотека для окон, графики, звука и видео на Python. Она работает напрямую с OpenGL и не требует других библиотек — только сам Python. На pyglet построен arcade, на нём делают игры, визуализации и мультимедийные программы.

В курсе вы соберёте по частям анимированную заставку с музыкой: фигуры, движение, управление, плавные переходы и звук. Как и раньше, задачи — готовые программы, в которых нужно починить сломанный участок.

Минимальная программа

import pyglet

window = pyglet.window.Window(800, 600, "Заставка")
batch = pyglet.graphics.Batch()
sun = pyglet.shapes.Circle(400, 300, 60, color=(255, 200, 0), batch=batch)


@window.event
def on_draw():
    window.clear()
    batch.draw()


pyglet.app.run()
  • pyglet.window.Window — окно. Его события (on_draw, on_key_press, on_mouse_press…) обрабатывают функции с декоратором @window.event.
  • on_draw вызывается, когда окно нужно перерисовать; начинается с window.clear().
  • pyglet.app.run() запускает цикл событий — программа работает, пока окно открыто.

Координаты

Как и в arcade, (0, 0) — левый нижний угол, y растёт вверх. Карту или текст, записанные сверху вниз, при рисовании переворачивают: строка row из rows — на высоте (rows - 1 - row) * cell.

Направление «по часовой стрелке от 12 часов» на угол a (в радианах):

x = cx + r * math.sin(a)
y = cy + r * math.cos(a)

Фигуры

from pyglet import shapes

rect = shapes.Rectangle(x, y, width, height, color=(255, 0, 0), batch=batch)   # (x, y) — левый нижний угол
circle = shapes.Circle(x, y, radius, color=(0, 200, 255), batch=batch)        # (x, y) — центр
line = shapes.Line(x1, y1, x2, y2, thickness=3, batch=batch)

У фигур можно менять поля прямо на ходу: rect.x = 100, rect.height = 50, circle.radius += 1, line.x2 = …, rect.color = (0, 255, 0), rect.opacity = 128 — изменения появятся в следующем кадре.

Батчи

Batch собирает фигуры, тексты и спрайты и рисует их одним вызовом batch.draw(). Это намного быстрее, чем рисовать каждую фигуру отдельно.

Фигура живёт, пока на неё есть ссылка. Если создать фигуру в цикле и не сохранить, Python её удалит — и она пропадёт с экрана. Поэтому фигуры хранят в списках:

stars = [shapes.Circle(x, y, 2, batch=batch) for x, y in points]

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

Окно создаётся под if __name__ == "__main__":. При «Отправить» проверка вызывает ваши функции без окна — иногда передавая им вместо настоящих фигур простые объекты с теми же полями (x, y, width…). Поэтому функции должны только задавать поля, а не создавать окна.

Итог

  • pyglet.window.Window, @window.event, on_draw, window.clear(), pyglet.app.run();
  • (0, 0) — левый нижний угол, y вверх;
  • shapes.Rectangle, Circle, Line; поля фигур можно менять на ходу;
  • Batch и batch.draw(); храните фигуры в переменных и списках.