Функции модуля pygame.draw рисуют геометрические примитивы на поверхности – экземпляре класса Surface. В качестве первого аргумента они принимают поверхность. Поэтому при создании той или иной поверхности ее надо связать с переменной, чтобы потом было что передать в функции модуля draw.
Поскольку мы пока используем только одну поверхность – главную оконную, то ее будем указывать в качестве первого параметра, а при создании свяжем с переменной:
import pygame as pg
import sys
sc = pg.display.set_mode((300, 200))
# здесь будут рисоваться фигуры
pg.display.update()
while 1:
for i in pg.event.get():
if i.type == pg.QUIT:
sys.exit()
pg.time.delay(1000)
В большинстве случаев фигуры прорисовывают внутри главного цикла, так как от кадра к кадру картинка на экране должна меняться. Поэтому на каждой итерации цикла в функции модуля draw передаются измененные аргументы (например, каждый раз меняется координата x).
Однако у нас пока не будет никакой анимации, и нет смысла перерисовывать фигуры на одном и том же месте на каждой итерации цикла. Поэтому создавать примитивы будем в основной ветке программы. На данном этапе цикл while нужен лишь для того, чтобы программа самопроизвольно не завершалась.
После прорисовки, чтобы увидеть изменения в окне игры, необходимо выполнить функцию update() или flip() модуля display. Иначе окно не обновится. Рисование на поверхности – одно, а обновление состояния главного окна – другое. Представьте, что в разных местах тела главного цикла на поверхности прорисовываются разные объекты. Если бы каждое такое действие приводило к автоматическому обновлению окна, то за одну итерацию оно обновлялось бы несколько раз. Это приводило бы как минимум к бессмысленной трате ресурсов, так как скорость цикла связана с FPS.
Итак, первый аргумент функций рисования – поверхность, на которой размещается фигура. В нашем случае это будет sc. Вторым обязательным аргументом является цвет. Цвет задается в формате RGB, используется трехэлементный целочисленный кортеж. Например, (255, 0, 0) определяет красный цвет.
Далее идут специфичные для каждой фигуры аргументы. Последним у большинства является толщина контура.
Все функции модуля draw возвращают экземпляры класса Rect – прямоугольные области, имеющие координаты, длину и ширину. Не путайте функцию rect() модуля draw и класс Rect, это разные вещи.
Начнем с функции rect() модуля draw:
pygame.draw.rect(sc, (255, 255, 255),
(20, 20, 100, 75))
pygame.draw.rect(sc, (64, 128, 255),
(150, 20, 100, 75), 8)

Если указывается толщина контура (последний аргумент во второй строке), то прямоугольник будет незаполненным, а цвет определит цвет рамки. Третьим аргументом является кортеж из четырех чисел. Первые два определяют координаты верхнего левого угла прямоугольника, вторые – его ширину и высоту.
Следует отметить, что в функцию draw.rect() и некоторые другие третьим аргументом можно передавать не кортеж, а заранее созданный экземпляр Rect. В примере ниже показан такой вариант.
Обычно цвета выносят в отдельные переменные-константы. Это облегчает чтение кода:
WHITE = (255, 255, 255) BLACK = (0, 0, 0) GRAY = (125, 125, 125) LIGHT_BLUE = (64, 128, 255) GREEN = (0, 200, 64) YELLOW = (225, 225, 0) PINK = (230, 50, 230) r1 = pygame.Rect((150, 20, 100, 75)) pygame.draw.rect(sc, WHITE, (20, 20, 100, 75)) pygame.draw.rect(sc, LIGHT_BLUE, r1, 8)
Чтобы нарисовать линию, а точнее – отрезок, надо указать координаты его концов. При этом функция line() рисует обычную линию, aaline() – сглаженную (толщину для последней указать нельзя):
pygame.draw.line(sc, WHITE,
[10, 30],
[290, 15], 3)
pygame.draw.line(sc, WHITE,
[10, 50],
[290, 35])
pygame.draw.aaline(sc, WHITE,
[10, 70],
[290, 55])

Координаты можно передавать как в виде списка, так и кортежа.
Функции lines() и aalines() рисуют ломанные линии:
pygame.draw.lines(sc, WHITE, True,
[[10, 10], [140, 70],
[280, 20]], 2)
pygame.draw.aalines(sc, WHITE, False,
[[10, 100], [140, 170],
[280, 110]])

Координаты определяют места излома. Количество точек может быть произвольным. Третий параметр (True или False) указывает замыкать ли крайние точки.
Функция polygon() рисует произвольный многоугольник. Задаются координаты вершин.
pygame.draw.polygon(sc, WHITE,
[[150, 10], [180, 50],
[90, 90], [30, 30]])
pygame.draw.polygon(sc, WHITE,
[[250, 110], [280, 150],
[190, 190], [130, 130]])
pygame.draw.aalines(sc, WHITE, True,
[[250, 110], [280, 150],
[190, 190], [130, 130]])

Сглаженная ломаная здесь повторяет контур многоугольника, чем сглаживает его ребра.
Так же как в случае rect() для polygon() можно указать толщину контура.
Функция circle() рисует круги. Указывается центр окружности и радиус:
pygame.draw.circle(sc, YELLOW,
(100, 100), 50)
pygame.draw.circle(sc, PINK,
(200, 100), 50, 10)

В случае эллипса передается описывающая его прямоугольная область:
pygame.draw.ellipse(sc, GREEN,
(10, 50, 280, 100))

Наконец, дуга:
pi = 3.14
pygame.draw.arc(sc, WHITE,
(10, 50, 280, 100),
0, pi)
pygame.draw.arc(sc, PINK,
(50, 30, 200, 150),
pi, 2*pi, 3)

Указывается прямоугольник, описывающий эллипс, из которого вырезается дуга. Четвертый и пятый аргументы – начало и конец дуги, выраженные в радианах. Нулевая точка справа.
Практическая работа. Анимация
На данном этапе мы уже готовы создать анимацию. Никакого движения объектов на экране монитора нет. Просто от кадра к кадру изменяются цвета пикселей экрана. Например, пиксель с координатами (10, 10) светится синим цветом, в следующем кадре синим загорается пиксель (11, 11), в то время как (10, 10) становится таким же как фон. В следующем кадре синей будет только точка (12, 12) и так далее. При этом человеку будет казаться, что синяя точка движется по экрану по диагонали.
Суть алгоритма в следующем. Берем фигуру. Рисуем ее на поверхности. Обновляем главное окно, человек видит картинку. Стираем фигуру. Рисуем ее с небольшим смещением от первоначальной позиции. Снова обновляем окно и так далее.
Как «стереть» старую фигуру? Для этого используется метод fill() объекта Surface. В качестве аргумента передается цвет, т. е. фон можно сделать любым, а не только черным, который задан по-умолчанию.
Ниже в качестве примера приводится код анимации круга. Объект появляется с левой стороны, доходит до правой, исчезает за ней. После этого снова появляется слева. Ваша задача написать код анимации квадрата, который перемещается от левой границе к правой, касается ее, но не исчезает за ней. После этого возвращается назад – от правой границы к левой, касается ее, опять двигается вправо. Циклы движения квадрата повторяются до завершения программы.
import pygame
import sys
FPS = 60
WIN_WIDTH = 400
WIN_HEIGHT = 100
WHITE = (255, 255, 255)
ORANGE = (255, 150, 100)
clock = pygame.time.Clock()
sc = pygame.display.set_mode(
(WIN_WIDTH, WIN_HEIGHT))
# радиус будущего круга
r = 30
# координаты круга
# скрываем за левой границей
x = 0 - r
# выравнивание по центру по вертикали
y = WIN_HEIGHT // 2
while 1:
for i in pygame.event.get():
if i.type == pygame.QUIT:
sys.exit()
# заливаем фон
sc.fill(WHITE)
# рисуем круг
pygame.draw.circle(sc, ORANGE,
(x, y), r)
# обновляем окно
pygame.display.update()
# Если круг полностью скрылся
# за правой границей,
if x >= WIN_WIDTH + r:
# перемещаем его за левую
x = 0 - r
else: # Если еще нет,
# на следующей итерации цикла
# круг отобразится немного правее
x += 2
clock.tick(FPS)
Источник: https://younglinux.info/