Rect — главный кубик игры
Rect — самый важный объект в Pygame. Это и позиция, и размер, и инструмент проверки столкновений в одном флаконе.
Суть: pygame.Rect хранит прямоугольную область и даёт десятки удобных свойств — center, topleft, right — а ещё умеет проверять пересечения. Это рабочая лошадка всей игры.
Если бы пришлось выбрать один объект Pygame, который ты будешь использовать чаще всего, это был бы Rect. Почти всё в 2D-игре — прямоугольник: герой, враг, монетка, кнопка, область экрана. Rect не просто хранит четыре числа, он даёт удобные «ручки», чтобы за них браться.
Хочешь поставить объект по центру экрана? Не нужно считать вручную — просто присвой rect.center = (400, 300), и Rect сам пересчитает свой угол. Хочешь узнать, где правая грань? rect.right. Хочешь прижать объект к низу окна? rect.bottom = HEIGHT. Эти свойства экономят тонну арифметики и багов.
Как работает под капотом
Внутри Rect хранит четыре числа: x, y, width, height. Все остальные свойства — это вычисления поверх них. Когда ты меняешь center, Rect пересчитывает x и y так, чтобы центр оказался на месте. Вот карта «ручек» прямоугольника:
topleft midtop topright
+-----------+-----------+
| | |
midleft center midright
| | |
+-----------+-----------+
bottomleft midbottom bottomright
.x .y = topleft .centerx .centery = center
В pygame это используется так:
player = pygame.Rect(0, 0, 50, 50) # x,y,w,h
player.center = (400, 300) # ставим по центру окна
print(player.topleft) # (375, 275)
player.x += 5 # сдвиг вправо
player.bottom = 600 # прижать к низу окна
# проверка пересечения с другим Rect
coin = pygame.Rect(380, 280, 20, 20)
if player.colliderect(coin):
print("Собрали монетку!")Логику свойств Rect легко воспроизвести на чистом Python. Сделаем мини-версию, которая умеет ставить центр и считать грани. Попробуй сам:
class MiniRect:
def __init__(self, x, y, w, h):
self.x, self.y, self.w, self.h = x, y, w, h
def set_center(self, cx, cy):
self.x = cx - self.w // 2 # пересчитываем угол из центра
self.y = cy - self.h // 2
@property
def center(self):
return (self.x + self.w // 2, self.y + self.h // 2)
r = MiniRect(0, 0, 50, 50)
r.set_center(400, 300)
print("угол topleft:", (r.x, r.y))
print("center снова:", r.center)
print("right:", r.x + r.w, "bottom:", r.y + r.h)Rect как универсальная зона
Rect полезен далеко за пределами «где находится спрайт». Им удобно описывать любую прямоугольную область с особым смыслом: зону, при входе в которую срабатывает ловушка; кнопку меню, по которой проверяют клик мыши; границы экрана, за которые нельзя выходить. Метод collidepoint(x, y) отвечает, попала ли точка (например, курсор) внутрь прямоугольника — так делают кликабельные кнопки. А contains проверяет, целиком ли один Rect внутри другого.
Ещё одна суперсила — методы движения. rect.move(dx, dy) возвращает новый сдвинутый прямоугольник, не меняя исходный, а rect.inflate(dx, dy) раздувает или сжимает его от центра — удобно делать хитбокс чуть меньше картинки. rect.clamp(area) возвращает Rect, втиснутый внутрь заданной области, — готовый способ не дать герою убежать за экран. Освоив эти методы, ты заметишь, что многие задачи, которые казались отдельными, на самом деле решаются одним вызовом Rect. Это и есть сила хорошо продуманного «кубика».
Привыкай читать код с Rect как предложения на русском. Строка enemy.rect.bottom = floor.top буквально говорит «поставь врага низом на верх пола» — и делает именно это, без единого вычисления вручную. Такой стиль самодокументирует логику: через месяц ты поймёшь свой код с одного взгляда. Ещё одна частая операция — держать объект внутри экрана: player.rect.clamp_ip(screen_rect) сам вернёт героя в границы, если тот выехал за край. Rect — это маленький, но удивительно богатый инструмент, и время, потраченное на изучение его свойств и методов, окупается в каждой следующей игре. Не зря говорят, что половина Pygame — это умелое обращение с прямоугольниками.
Частые ошибки
- Двигать объект, меняя только
x, но проверятьcenter— путаница в том, что считается позицией. - Хранить float-позицию прямо в Rect — Rect округляет до целых, дробная часть теряется. Держи точную позицию отдельно.
- Считать грани вручную вместо
rect.right— лишний код и ошибки.
Best practices
- Используй именованные свойства (
center,bottom) — код читается как описание сцены. - Точную позицию храни во Vector2, а Rect синхронизируй для отрисовки и коллизий.
- Для проверки столкновений всегда есть
colliderect— не изобретай велосипед.
Итог: Rect — это позиция, размер и детектор столкновений в одном объекте. Освой его свойства, и половина рутины исчезнет.