Модуль pygame.draw
Функции модуля 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)
Курс с примерами решений практических работ:
pdf-версия
X Скрыть Наверх
Pygame. Введение в разработку игр на Python
Добавляем легенду и рисуем геометрические фигуры на графиках
Давайте предположим, что в наших координатных осях показаны два графика:
import numpy as np import matplotlib.pyplot as plt fig = plt.figure(figsize=(7, 4)) ax = fig.add_subplot() ax.plot(np.arange(0, 5, 0.25)) ax.plot(np.arange(0, 10, 0.5)) plt.show()
Если мы теперь попытаемся отобразить легенду – их краткое описание, с помощью метода:
ax.legend()
то увидим пустой квадратик в верхнем левом углу. Почему в нем ничего нет? Дело в том, что нам нужно для каждой линии (графика) добавить символьное имя. Это делается с помощью именованного параметра label:
ax.plot(np.arange(0, 5, 0.25), label='line1') ax.plot(np.arange(0, 10, 0.5), label='line2')
Теперь, при запуске программы мы видим следующее окно:

Причем, легенда использует цвет и тип линии графика и если его изменить, например, так:
ax.plot(np.arange(0, 5, 0.25), '--o', label='line1') ax.plot(np.arange(0, 10, 0.5), ':s', label='line2')
то это автоматически приведет к изменению и в окне легенды:

Также мы можем самостоятельно указывать метки линий при отображении легенды. Для этого достаточно передать список меток в метод legend():
ax.legend(['1', '2'])
Соответственно, параметры label в этом случае можно уже не прописывать.
Наконец, в третьем варианте, мы можем указать список линий и меток при отображении информации в легенде:
line1, = ax.plot(np.arange(0, 5, 0.25), '--o', label='line1') line2, = ax.plot(np.arange(0, 10, 0.5), ':s', label='line2') ax.legend((line2, line1), ['Линия 2', 'Линия 1'])
Далее, с помощью параметра loc можно указывать расположение окна легенды в пределах координатных осей. Этот параметр может принимать следующие значения:
[‘best’, ‘upper right’, ‘upper left’, ‘lower left’, ‘lower right’, ‘right’, ‘center left’, ‘center right’, ‘lower center’, ‘upper center’, ‘center’]
Названия здесь говорят сами за себя. Например, можно записать:
ax.legend((line2, line1), ['Линия 2', 'Линия 1'], loc='upper right')
и легенда будет расположена в верхнем правом углу. Аналогично используются и другие значения.
Если требуется более точное указание местоположения легенды, то можно воспользоваться параметром bbox_to_anchor и указать координаты информационного окна:
ax.legend((line2, line1), ['Линия 2', 'Линия 1'], bbox_to_anchor=(0.5, 0.7))
Здесь значения прописываются в диапазоне от 0 до 1 как доли от размеров координатных осей.
Пакет matplotlib позволяет отображать формулы, записанные в формате TeX. Для этого описание нужно заключить между символами $ и использовать режим записи r (row – «сырая» строка без экранирования символов). Например, можно сформировать следующие подписи у графиков:
ax.legend((line2, line1), [r'$f(x) = a \cdot b + c$', r'$f(x) = k \cdot x + b$'])
В результате, увидим такое окно легенды:

Причем, такую TeX-нотацию можно применять для любых текстовых элементов пакета matplotlib.
Использование библиотеки Matplotlib. Как рисовать линии и геометрические фигуры на графике
Matplotlib позволяет рисовать на графиках различные геометрические фигуры, стрелки, а также линии, заданные различными способами. В этой статье будут рассмотрены основные моменты, характерные для рисования различных геометрических фигур. В качестве примера будет рассматриваться скрипт, который рисует следующую картинку:

Все геометрические объекты на графике рисуются в несколько шагов. Сначала нужно получить (или создать) оси, привязанные к текущему графику. Делается это с помощью функции gca() из модуля matplotlib.pyplot. Эта функция вернет класс, производный от matplotlib.axes.Axes, в нашем примере это будет класс AxesSubplot.
После этого нужно создать объект геометрической фигуры, классы которых содержатся в модуле matplotlib.patches для большинства геометрических фигур, однако класс линий Line2D содержится в модуле matplotlib.lines. В то же время те же самые геометрические фигуры можно создавать, используя модуль matplotlib.pyplot, о чем будет сказано ниже, но для начала мы будем использовать модули matplotlib.patches и matplotlib.lines.
После создания объекта геометрической фигуры мы должны добавить ее в оси с помощью метода add_patch() для большинства геометрических фигур или с помощью метода add_line() для экземпляра класса Line2D.
Не будем подробно рассматривать каждый создаваемый в данном примере объект, у них может быть достаточно большое количество параметров, в этой статье обратим внимание лишь на некоторые особенности, которые могут показаться не очень логичными или о которых легко забыть.
Для наглядности в данном примере рисование каждого вида объекта вынесено в отдельную функцию. Сначала посмотрим полный код данного примера, а потом рассмотрим особенности некоторых объектов.
import matplotlib. patches
import matplotlib. path
import matplotlib. pyplot as plt
from matplotlib. lines import Line2D
def drawLine ( axes ) :
«»»
Рисование линии
«»»
x0 = 0
y0 = 0
line = Line2D ( [ x0 , x1 , x2 ] , [ y0 , y1 , y2 ] , color = «k» )
axes. add_line ( line )
plt. text ( 0.5 , 1.1 , «Line2D» , horizontalalignment = «center» )
def drawCircles ( axes ) :
«»»
Рисование окружностей
«»»
circle1 = matplotlib. patches . Circle ( ( 0 , 0 ) , radius = 0.1 , fill = True )
axes. add_patch ( circle1 )
plt. text ( 0 , 0.2 , «Circle» , horizontalalignment = «center» )
circle2 = matplotlib. patches . Circle ( ( 0 , 0 ) ,
radius = 1.5 ,
fill = False ,
color = «r» )
axes. add_patch ( circle2 )
plt. text ( 0 , 1.55 , «Circle» , horizontalalignment = «center» )
def drawArrow ( axes ) :
«»»
Рисование стрелки
«»»
arrow_x0 = — 1.0
arrow_y0 = 0.5
arrow_dx = 1
arrow_dy = 0.5
arrow = matplotlib. patches . Arrow ( arrow_x0 ,
arrow_y0 ,
arrow_dx ,
arrow_dy ,
width = 0.2 ,
color = «g» )
axes. add_patch ( arrow )
plt. text ( — 0.5 , 1.0 , «Arrow» , horizontalalignment = «center» )
def drawArc ( axes ) :
«»»
Рисование дуги
«»»
arc_x = 0
arc_y = 0
arc_width = 1
arc_height = 1
arc_theta1 = 270
arc_theta2 = 360
arc = matplotlib. patches . Arc ( ( arc_x , arc_y ) ,
arc_width ,
arc_height ,
theta1 = arc_theta1 ,
theta2 = arc_theta2 )
axes. add_patch ( arc )
plt. text ( 0.6 , — 0.3 , «Arc» , horizontalalignment = «center» )
def drawPolygons ( axes ) :
«»»
Рисование многоугольника
«»»
polygon_1 = matplotlib. patches . Polygon ( [ ( 0 , — 0.75 ) ,
( 0 , — 1.25 ) ,
( 0.5 , — 1.25 ) ,
( 1 , — 0.75 ) ] )
axes. add_patch ( polygon_1 )
plt. text ( 0.6 , — 0.7 , «Polygon» , horizontalalignment = «center» )
polygon_2 = matplotlib. patches . Polygon ( [ ( — 0.5 , 0 ) ,
( — 1 , — 0.5 ) ,
( — 1 , — 1 ) ,
( — 0.5 , — 1 ) ] ,
fill = False ,
closed = False )
axes. add_patch ( polygon_2 )
plt. text ( — 1.0 , — 0.1 , «Polygon» , horizontalalignment = «center» )
def drawRect ( axes ) :
«»»
Рисование повернутого прямоугольника
«»»
rect_coord = ( — 1.5 , 1 )
rect_width = 0.5
rect_height = 0.3
rect_angle = 30
rect = matplotlib. patches . Rectangle ( rect_coord ,
rect_width ,
rect_height ,
rect_angle ,
color = «g» )
axes. add_patch ( rect )
plt. text ( — 1.5 , 1.5 , «Rect» , horizontalalignment = «center» )
def drawPath ( axes ) :
vertices = [ ( 1.0 , — 1.75 ) , ( 1.5 , — 1.5 ) , ( 1.5 , — 1.0 ) , ( 1.75 , — 0.75 ) ]
codes = [ matplotlib. path . Path . MOVETO ,
matplotlib. path . Path . LINETO ,
matplotlib. path . Path . LINETO ,
matplotlib. path . Path . LINETO ,
]
path = matplotlib. patches . Path ( vertices , codes )
path_patch = matplotlib. patches . PathPatch ( path , fill = False )
axes. add_patch ( path_patch )
plt. text ( 1.5 , — 1.75 , «Path» , horizontalalignment = «center» )
if __name__ == «__main__» :
plt. xlim ( — 2 , 2 )
plt. ylim ( — 2 , 2 )
plt. grid ( )
# Получим текущие оси
axes = plt. gca ( )
axes. set_aspect ( «equal» )
drawLine ( axes )
drawPolygons ( axes )
drawPath ( axes )
drawRect ( axes )
drawCircles ( axes )
drawArc ( axes )
drawArrow ( axes )
Начнем разбор примера с рисования линий.
Создание класса «Геометрическая фигура»
помогите доделать программу, выводит ошибку.
Создайте класс Геометрическая фигура (динамические методы: вывод информации, площадь, периметр). Создать три производных от Геометрической фигуры класса: Прямоугольник (поля: стороны), Круг (поля: радиус, координаты центра), Треугольник (поля: стороны). Переопределить для производных классов методы вывод информации, площадь, периметр. Добавить в класс Круг метод вывода уравнения окружности, в класс Прямоугольник – метод масштабирования (обе стороны умножаются на одно и то же число). Продемонстрировать работу всех методов. Вот задание
Вот мой код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
class Fig: def __init__(self, s, p): self.s=s self.p=p def information_employee(self): print('S = <> '.format(self.s)) print('P = <> '.format(self.p)) class Rectangle(Fig): def __init__(self, a, b, k): self.a=a self.b=b self.k=k def rectangle (self): print('a = <>'.format(self.a)) print('b = <>'. format(self.b)) print('S = <> '.format(self.s)) print('P = <> '.format(self.p)) def scale (self, k): return self.a*self.k or self.b*self.k class Circle(Fig): def __init__(self, r, O): self.r=r self.O=O def circle (self): print('r = <>'.format(self.r)) print('O = <>'.format(self.O)) print('S = <> '.format(self.s)) print('P = <> '.format(self.p)) class Triangle(Fig): def __init__(self, a, b, c): self.a=a self.b=b self.c=c def triangle (self): print('a = <>'.format(self.a)) print('b = <>'.format(self.b)) print('c = <>'.format(self.c)) print('S = <> '.format(self.s)) print('P = <> '.format(self.p)) a=Fig("0", "0") b=Circle("2", "(1, -1)") c=Rectangle("1", "1") d=Triangle("3", "4", "5") a.information_employee() b.information_employee() c.information_employee() d.information_employee()
