pygame draw rect что это
Рисование графических примитивов
Обратите внимание у всех этих функций первым параметром идет surface – поверхность, на которой выполняется рисование. Забегая вперед отмечу, что таких поверхностей можно создавать множество, накладывая друг на друга. Но на этом занятии мы будем использовать базовую поверхность, представляющую клиентскую область окна приложения:
Ссылку на этот объект можно получить в момент создания окна:
(здесь sc – ссылка на базовый объект Surface). Давайте теперь нарисуем в окне прямоугольник с помощью функции rect:
В данном случае мы включаем все три цветовые компоненты по максимуму и получаем белый цвет. Далее, размеры прямоугольника определяются по формату:
Обратите внимание, что координаты откладываются от верхнего левого угла и ось Oy направлена вниз (а не вверх, как мы привыкли по математике).
Итак, указание нарисовать прямоугольник даны. Но если сейчас выполнить программу, то мы ничего не увидим на экране. Почему? Это связано с тем, что базовый объект Surface использует механизм рисования, известный как буферизация вывода.
Ее принцип проще пояснить на таком рисунке. Представим, что объект Surface имеет две стороны A и B:
Изначально мы видим сторону B, но рисование выполняется на противоположной стороне – A. Затем, чтобы отобразить нарисованные объекты, мы должны перевернуть объект Surface другой стороной. В PyGame это делается с помощью функции flip():
Теперь при запуске программы мы видим сторону A с нарисованным прямоугольником. В этом заключается принцип буферизации вывода графической информации. Но спрашивается: зачем все это нужно? Почему бы сразу не рисовать на видимой стороне объекта? В этом случае при большом числе объектов и сложной анимации пользователь будет замечать процесс отрисовки текущего кадра игры. И это негативно скажется на визуальном восприятии игрового процесса. Чтобы перерисовка кадров проходила незаметно для человеческого глаза, как раз и используется механизм буферизации.
Помимо метода flip() можно использовать похожий метод:
Здесь rectangle – это прямоугольная область, которую требуется перерисовать (по умолчанию, если ничего не указано, то перерисовывается вся клиентская область и метод update повторяет метод flip).
Так как метод update более гибкий, то в дальнейшем я буду использовать именно его.
Итак, мы с вами нарисовали закрашенный прямоугольник. Если нужно нарисовать не закрашенный, то следует указать следующий параметр – толщину линии:
Разумеется, все функции рисования должны следовать до метода update. Наконец, последний важный штрих. Цвета заливки или линий обычно задаются вначале в виде констант, а затем, уже используются в функциях рисования:
Так программа выглядит более читабельной. Давайте теперь посмотрим как рисуются остальные графические примитивы:
Вот такие примитивы существуют в PyGame.
Видео по теме
Что такое Pygame? Каркас приложения, FPS | Pygame #1
Рисование графических примитивов | Pygame #2
Как обрабатывать события от клавиатуры | Pygame #3
Как обрабатывать события от мыши | Pygame #4
Создание поверхностей (Surface) и их анимация. Метод blit | Pygame #5
Класс Rect. Его роль, свойства и методы | Pygame #6
Как рисовать текст различными шрифтами | Pygame #7
Как работать с изображениями. Модули image и transform | Pygame #8
Что такое спрайты и как с ними работать | Pygame #9
Как делать контроль столкновений | Pygame #10
Добавляем звук в игровой процесс. Модули mixer и music | Pygame #11
© 2021 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта
Класс Rect
Еще одни ключевым классом в Pygame является Rect. Его экземпляры представляют собой прямоугольные области. Они не имеют графического представления в окне игры. Ценность класса заключается в свойствах и методах, позволяющих управлять размещением поверхностей, выполнять проверку их перекрытия и др.
Rect’ы можно передавать в функцию pygame.display.update(). В этом случае будут обновляться только соответствующие им области.
Экземпляры Rect создаются не только напрямую от класса. Однако начнем с этого варианта.
В конструктор класса Rect передаются четыре числа – координаты x и y, ширина и высота. Мы создаем два квадрата со сторонами в 30 пикселей. Верхний левый угол первого находится в точке (0, 0), второго – (30, 30).
У объектов Rect есть более десятка свойств, связанных с их координатами и размерами. Свойство bottomright одно из них, в нем хранится координата нижнего правого угла. Понятно, что если второй квадрат начинается в точке (30, 30) и его сторона равна 30, то нижний правый угол будет в точке (60, 60).
Кроме свойств, у объектов Rect есть множество методов. Метод move_ip() смещает прямоугольную область по оси x (первый аргумент) и y (второй аргумент) на указанное количество пикселей. В данном случае если второй прямоугольник смещается на 10 пикселей по обоим осям, то его левый верхний угол окажется в точке (40, 40).
Метод union_ip() присоединяет к тому прямоугольнику, к которому применяется, другой – который передается аргументом. Когда мы отодвинули второй прямоугольник на 10 пикселей, то область, заключающая в себе оба, уже будет шириной 70 пикселей, а не 60.
Методы, у которых есть суффикс _ip, изменяют тот экземпляр Rect, к которому применяются. Есть аналогичные методы без _ip (например, move(), union()), которые возвращают новый экземпляр, т. е. старый остается без изменений.
В метод blit() можно передавать не координаты места размещения Surface, а экземпляр Rect. Метод blit() сам возьмет из Rect координаты его верхнего левого угла:
Мы размещаем желтую поверхность на зеленой, а белую – на желтой. В обоих случаях – в координатах (70, 20). Однако в каждом случае точка берется относительно своей родительской поверхности.
Еще один момент, на который надо обратить внимание. Прямоугольная область была определена нулевой размерностью. При этом поверхности отобразились соответственно своим собственным размерам. Это значит, что поверхности не располагаются внутри rect’ов. Они к ним никакого отношения не имеют. Из прямоугольников blit() взял только координаты.
С другой стороны, экземпляры Rect предназначены для хранения не только координат, но и размеров поверхностей. Размеры в основном нужны для проверки коллизий. В большинстве случаев сначала создается поверхность. Далее с нее снимается «маска», т. е. создается экземпляр Rect, который будет иметь те же размеры, что и она. Все дальнейшее «взаимодействие» поверхности с другими объектами (размещение, проверка столкновений и вхождений) происходит через «связанный» с ней Rect.
Метод поверхности get_rect() возвращает экземпляр Rect, ширина и высота которого совпадают с таковыми поверхности. В примере метод get_width() возвращает ширину поверхности, также выводится ширина прямоугольника (rect.width), чтобы показать, что они равны.
Если в get_rect() не передавать аргументы, то верхний левый угол экземпляра Rect будет в точке (0, 0).
В цикле мы изменяем координату x прямоугольной области, после чего передаем уже измененный rect в метод blit(). В результате поверхность будет двигаться.
Мораль такова. Нам не нужно вводить множество переменных для хранения координат и размеров. Для каждой поверхности заводится свой rect, который хранит в себе множество свойств и включает ряд полезных методов.
В get_rect() можно передавать именованные аргументы, являющиеся свойствами Rect, и устанавливать им значения. Например, surf.get_rect(topleft=(100, 50)) вернет прямоугольник, чей левый угол будет в точке (100, 50), а размер совпадать с размерами surf. Выражение surf.get_rect(centerx=100) вернет прямоугольник, координата x центра которого будет иметь значение 100. При этом остальные координаты будут вычислены, исходя из размеров поверхности.
Перепишем программу с двумя ракетами из предыдущего урока, используя экземпляры Rect.
Главное, на что здесь следует обратить внимание, – вызов функции pygame.display.update() с аргументом-прямоугольником. Таким образом, на каждой итерации главного цикла while в памяти компьютера «перерисовывается» только часть окна, что экономит его ресурсы.
Создаются два экземпляра Rect. Левый начинается в верхнем левом углу окна, правый – от цента по оси x, вверху по оси y.
При создании экземпляров Surface мы указываем такую же ширину и высоту как у соответствующих им прямоугольников.
Левая и правая поверхности прорисовываются на главном окне. Координаты берутся из соответствующих экземпляров Rect.
Создаются два экземпляра нашего самописного класса Rocket. Конструктору надо передать поверхность и цвет.
Переменные определяют, какую анимацию проигрывать. Пока не будет произведено кликов, то никакую.
Метод collidepoint() объекта Rect проверяет, находится ли точка, координаты которой были переданы в качестве аргумента, в пределах прямоугольника, к которому применяется метод. Здесь точкой являются координаты клика мыши. Если клик происходит в левом прямоугольнике, то в True устанавливается одна переменная, если в правом – то другая.
В зависимости от того, какая переменная в статусе True, изменения происходят только на одной из двух дочерних поверхностей. Также как update() метод blit() вызывается на каждой итерации, иначе изменения не будут видны.
Практическая работа
Напишите программу по следующему описанию. В центре окна находится круг, изменяющий свой цвет на каждой итерации цикла. Окно условно поделено на четверти: верхнюю левую, верхнюю правую, нижнюю левую, нижнюю правую. Если нажимается клавиша 1, то обновляются только две четверти по диагонали. Если 2 – то только две другие. Нажатие нуля возобновляет обновление всей поверхность.
Примечание. Функция pygame.display.update() может принимать не только один экземпляр Rect, но и список таковых.
Шапошникова С. (plustilino) © 2020
Pygame. Введение в разработку игр на Python
Pygame draw rect что это
Draw several simple shapes to a surface. These functions will work for rendering to any format of surface. Rendering to hardware surfaces will be slower than regular software surfaces.
Most of the functions take a width argument to represent the size of stroke (thickness) around the edge of the shape. If a width of 0 is passed the shape will be filled (solid).
All the drawing functions respect the clip area for the surface and will be constrained to that area. The functions return a rectangle representing the bounding area of changed pixels. This bounding rectangle is the ‘minimum’ bounding box that encloses the affected area.
All the drawing functions accept a color argument that can be one of the following formats:
an (RGB) triplet (tuple/list)
an (RGBA) quadruplet (tuple/list)
A color’s alpha value will be written directly into the surface (if the surface contains pixel alphas), but the draw function will not draw transparently.
These functions temporarily lock the surface they are operating on. Many sequential drawing calls can be sped up by locking and unlocking the surface object around the draw calls (see pygame.Surface.lock() lock the Surface memory for pixel access and pygame.Surface.unlock() unlock the Surface memory from pixel access ).
See the pygame.gfxdraw pygame module for drawing shapes module for alternative draw methods.
Draws a rectangle on the given surface.
(optional) used for line thickness or to indicate that the rectangle is to be filled (not to be confused with the width value of the rect parameter)
(optional) used for setting the value of bottom right border. If you don’t set this value, it will use the border_radius value.
a rect bounding the changed pixels, if nothing is drawn the bounding rect’s position will be the position of the given rect parameter and its width and height will be 0
The pygame.Surface.fill() fill Surface with a solid color method works just as well for drawing filled rectangles and can be hardware accelerated on some platforms with both software and hardware display modes.
Changed in pygame 2.0.0: Added support for keyword arguments.
Changed in pygame 2.0.0.dev8: Added support for border radius.
Draws a polygon on the given surface.
(optional) used for line thickness or to indicate that the polygon is to be filled
a rect bounding the changed pixels, if nothing is drawn the bounding rect’s position will be the position of the first point in the points parameter (float values will be truncated) and its width and height will be 0
Changed in pygame 2.0.0: Added support for keyword arguments.
Draws a circle on the given surface.
(optional) used for line thickness or to indicate that the circle is to be filled
(optional) if this is set to True then the bottom right corner of the circle will be drawn
a rect bounding the changed pixels, if nothing is drawn the bounding rect’s position will be the center parameter value (float values will be truncated) and its width and height will be 0
Changed in pygame 2.0.0: Added support for keyword arguments. Nothing is drawn when the radius is 0 (a pixel at the center coordinates used to be drawn when the radius equaled 0). Floats, and Vector2 are accepted for the center param. The drawing algorithm was improved to look more like a circle.
Changed in pygame 2.0.0.dev8: Added support for drawing circle quadrants.
Draws an ellipse on the given surface.
(optional) used for line thickness or to indicate that the ellipse is to be filled (not to be confused with the width value of the rect parameter)
a rect bounding the changed pixels, if nothing is drawn the bounding rect’s position will be the position of the given rect parameter and its width and height will be 0
Changed in pygame 2.0.0: Added support for keyword arguments.
Draws an elliptical arc on the given surface.
stop angle of the arc in radians
(optional) used for line thickness (not to be confused with the width value of the rect parameter)
a rect bounding the changed pixels, if nothing is drawn the bounding rect’s position will be the position of the given rect parameter and its width and height will be 0
Changed in pygame 2.0.0: Added support for keyword arguments.
Draws a straight line on the given surface. There are no endcaps. For thick lines the ends are squared off.
(optional) used for line thickness
For odd width values, the thickness of each line grows with the original line being in the center.
For even width values, the thickness of each line grows with the original line being offset from the center (as there is no exact center line drawn). As a result, lines with a slope = 1 (vertical-ish) will have 1 more pixel of thickness to the right of the original line (in the x direction).
a rect bounding the changed pixels, if nothing is drawn the bounding rect’s position will be the start_pos parameter value (float values will be truncated) and its width and height will be 0
Changed in pygame 2.0.0: Added support for keyword arguments.
Draws a sequence of contiguous straight lines on the given surface. There are no endcaps or miter joints. For thick lines the ends are squared off. Drawing thick lines with sharp corners can have undesired looking results.
(optional) used for line thickness
a rect bounding the changed pixels, if nothing is drawn the bounding rect’s position will be the position of the first point in the points parameter (float values will be truncated) and its width and height will be 0
Changed in pygame 2.0.0: Added support for keyword arguments.
Draws a straight antialiased line on the given surface.
The line has a thickness of one pixel and the endpoints have a height and width of one pixel each.
The way a line and it’s endpoints are drawn:
If both endpoints are equal, only a single pixel is drawn (after rounding floats to nearest integer).
Otherwise if the line is not steep (i.e. if the length along the x-axis is greater than the height along the y-axis):
Calculate the position of the nearest point with a whole number for it’s x-coordinate, when extending the line past the endpoint.
Find which pixels would be covered and how much by that point.
Then draw those pixels.
Then for each point between the endpoints, along the line, whose x-coordinate is a whole number:
Find which pixels would be covered and how much by that point and draw them.
a rect bounding the changed pixels, if nothing is drawn the bounding rect’s position will be the start_pos parameter value (float values will be truncated) and its width and height will be 0
Changed in pygame 2.0.0: Added support for keyword arguments.
Draws a sequence of contiguous straight antialiased lines on the given surface.
a rect bounding the changed pixels, if nothing is drawn the bounding rect’s position will be the position of the first point in the points parameter (float values will be truncated) and its width and height will be 0
Changed in pygame 2.0.0: Added support for keyword arguments.
Модуль pygame.draw
Функции модуля pygame.draw рисуют геометрические примитивы на поверхности – экземпляре класса Surface. В качестве первого аргумента они принимают поверхность. Поэтому при создании той или иной поверхности ее надо связать с переменной, чтобы потом было что передать в функции модуля draw.
Поскольку мы пока используем только одну поверхность – главную оконную, то ее будем указывать в качестве первого параметра, а при создании свяжем с переменной:
В большинстве случаев фигуры прорисовывают внутри главного цикла, так как от кадра к кадру картинка на экране должна меняться. Поэтому на каждой итерации цикла в функции модуля draw передаются измененные аргументы (например, каждый раз меняется координата x).
Однако у нас пока не будет никакой анимации, и нет смысла перерисовывать фигуры на одном и том же месте на каждой итерации цикла. Поэтому создавать примитивы будем в основной ветке программы. На данном этапе цикл while нужен лишь для того, чтобы программа самопроизвольно не завершалась.
После прорисовки, чтобы увидеть изменения в окне игры, необходимо выполнить функцию update() или flip() модуля display. Иначе окно не обновится. Рисование на поверхности – одно, а обновление состояния главного окна – другое. Представьте, что в разных местах тела главного цикла на поверхности прорисовываются разные объекты. Если бы каждое такое действие приводило к автоматическому обновлению окна, то за одну итерацию оно обновлялось бы несколько раз. Это приводило бы как минимум к бессмысленной трате ресурсов, так как скорость цикла связана с FPS.
Далее идут специфичные для каждой фигуры аргументы. Последним у большинства является толщина контура.
Все функции модуля draw возвращают экземпляры класса Rect – прямоугольные области, имеющие координаты, длину и ширину. Не путайте функцию rect() модуля draw и класс Rect, это разные вещи.
Начнем с функции rect() модуля draw:
Если указывается толщина контура (последний аргумент во второй строке), то прямоугольник будет незаполненным, а цвет определит цвет рамки. Третьим аргументом является кортеж из четырех чисел. Первые два определяют координаты верхнего левого угла прямоугольника, вторые – его ширину и высоту.
Следует отметить, что в функцию draw.rect() и некоторые другие третьим аргументом можно передавать не кортеж, а заранее созданный экземпляр Rect. В примере ниже показан такой вариант.
Обычно цвета выносят в отдельные переменные-константы. Это облегчает чтение кода:
Чтобы нарисовать линию, а точнее – отрезок, надо указать координаты его концов. При этом функция line() рисует обычную линию, aaline() – сглаженную (толщину для последней указать нельзя):
Координаты можно передавать как в виде списка, так и кортежа.
Функции lines() и aalines() рисуют ломанные линии:
Координаты определяют места излома. Количество точек может быть произвольным. Третий параметр (True или False) указывает замыкать ли крайние точки.
Функция polygon() рисует произвольный многоугольник. Задаются координаты вершин.
Сглаженная ломаная здесь повторяет контур многоугольника, чем сглаживает его ребра.
Так же как в случае rect() для polygon() можно указать толщину контура.
Функция circle() рисует круги. Указывается центр окружности и радиус:
В случае эллипса передается описывающая его прямоугольная область:
Указывается прямоугольник, описывающий эллипс, из которого вырезается дуга. Четвертый и пятый аргументы – начало и конец дуги, выраженные в радианах. Нулевая точка справа.
Практическая работа. Анимация
На данном этапе мы уже готовы создать анимацию. Никакого движения объектов на экране монитора нет. Просто от кадра к кадру изменяются цвета пикселей экрана. Например, пиксель с координатами (10, 10) светится синим цветом, в следующем кадре синим загорается пиксель (11, 11), в то время как (10, 10) становится таким же как фон. В следующем кадре синей будет только точка (12, 12) и так далее. При этом человеку будет казаться, что синяя точка движется по экрану по диагонали.
Суть алгоритма в следующем. Берем фигуру. Рисуем ее на поверхности. Обновляем главное окно, человек видит картинку. Стираем фигуру. Рисуем ее с небольшим смещением от первоначальной позиции. Снова обновляем окно и так далее.
Как «стереть» старую фигуру? Для этого используется метод fill() объекта Surface. В качестве аргумента передается цвет, т. е. фон можно сделать любым, а не только черным, который задан по-умолчанию.
Ниже в качестве примера приводится код анимации круга. Объект появляется с левой стороны, доходит до правой, исчезает за ней. После этого снова появляется слева. Ваша задача написать код анимации квадрата, который перемещается от левой границе к правой, касается ее, но не исчезает за ней. После этого возвращается назад – от правой границы к левой, касается ее, опять двигается вправо. Циклы движения квадрата повторяются до завершения программы.
Шапошникова С. (plustilino) © 2020
Pygame. Введение в разработку игр на Python
Pygame draw rect что это
Те, кто хорошо поняли прошлую статью, могут сказать, что этот метод создает окно с размерами 400х100. На самом деле все немного не так, вернее все так только я тогда полностью не объяснил весь метод, если простыми словами, то этот метод создает окно и возвращает изображение, которым является поверхность окна. Наверное я вас запутал, сейчас попробую это исправить, давайте рассмотрим этот метод более детально.
pygame.display.set_mode(resolution=(0,0), flags=0, depth=0): return Surface, здесь resolution – это список чисел в котором хранится размер окна по оси х и у, flags – флаг окна (полный экран, изменяемые размеры и и т.д), depth – глубина цвета. Как видно описание такое же, как и в прошлой статье, но есть одно но, тогда мы не рассмотрели то, что возвращает этот метод. Как видно этот метод возвращает объект класса Surface. Surface – если перевести на русский будет – поверхность, в целом это правильный перевод, но что тогда принимать за поверхность? Поверхность в данном контексте это объект, на котором мы можем рисовать, например если сравнивать PyGame с другими графическими библиотеками, то там поверхность рисования называется Canvas, Image и т.д. По сути, класс Surface это представление изображения в библиотеки PyGame. Далее изображение и поверхность рисования будут иметь одинаковый смысл. Про класс Surface мы с вами поговорим в следующих статьях, сейчас вам главное понять то, что Surface это изображение в PyGame.
Теперь мы знаем, что есть девять методов, которые рисуют на изображении простые фигуры, но изучать их сейчас мы не будем, все это будет потом, а сейчас нам надо построить скелет программы на PyGame.
Часть вторая. Составление скелета программы на PyGame.
Часть третья. Практика и теория.
В итоге должен быть написан следующий код:
Часть четвертая. Заключение.
В итоге мы рассмотрели полностью класс Draw библиотеки PyGame, поняли, что из себя представляет класс Surface и написали шаблон, который мы будем использовать в следующих статьях. В следующей статье мы поговорим об событиях в PyGame.
Если есть, вопросы или проблемы по статье обращайтесь ко мне в Л.С.
Все всем пока, желаю удачи в геймдеве. Спасибо за внимание с вами был noTformaT.