</>
Тема 3 из 6

Rect и движение

Всё, что движется в игре, удобно описывать прямоугольником pygame.Rect: игрок, пуля, платформа, кнопка. Он хранит положение и размер и умеет сдвигаться, проверять пересечения и не выходить за границы.

Rect

import pygame

r = pygame.Rect(10, 20, 30, 40)   # x, y, ширина, высота
print(r.x, r.y, r.w, r.h)         # 10 20 30 40
print(r.right, r.bottom)          # 40 60  (x + w, y + h)
print(r.center, r.topleft)        # (25, 40) (10, 20)

У прямоугольника много «ручек»: left, right, top, bottom, centerx, centery, center, topleft, midbottom… Их можно не только читать, но и присваивать — прямоугольник сдвинется целиком, размер не изменится:

r.bottom = 100     # теперь нижняя сторона на 100, а y = 60
r.center = (0, 0)  # центр в начале координат

Это удобнее, чем пересчитывать x и y вручную: «поставить на землю» — это r.bottom = GROUND, а не r.y = GROUND - r.h.

Координаты у Rect — целые числа: дробная часть отбрасывается.

Движение

Движение в игре — это изменение координат каждый кадр:

r.x += 5             # на 5 пикселей вправо за кадр
r.move_ip(5, -2)     # сразу по двум осям
r2 = r.move(5, -2)   # новый прямоугольник, r не меняется

При 60 кадрах в секунду скорость 5 пикселей за кадр — это 300 пикселей в секунду.

Не выйти за экран

field = screen.get_rect()   # Rect(0, 0, ширина, высота)
r.clamp_ip(field)           # сдвинуть r внутрь field, если он вылез
print(field.contains(r))    # True, если r целиком внутри

clamp_ip прижимает прямоугольник к ближайшему краю — по обеим осям сразу. Писать это вручную легко с ошибкой: забыть ось, сравнить не ту сторону, ошибиться на один пиксель.

Гравитация и прыжок

Чтобы движение выглядело естественно, у объекта хранят скорость и меняют её каждый кадр:

vy += GRAVITY        # гравитация разгоняет вниз
player.y += vy       # двигаем на текущую скорость
if player.bottom >= GROUND:   # коснулись земли
    player.bottom = GROUND    # ставим ровно на землю
    vy = 0

Прыжок — это просто отрицательная скорость: vy = -15. Дальше гравитация сама замедлит подъём и вернёт персонажа вниз. Прыгать можно только с земли — иначе получится «полёт».

Перенос через край

В аркадах объект, ушедший за край, часто появляется с другой стороны. Важно решить, когда переносить (когда коснулся края или когда скрылся целиком) и куда ставить (чтобы он плавно въехал, а не возник целиком).

Итог

  • pygame.Rect(x, y, w, h): right, bottom, center… — читать и присваивать;
  • move_ip(dx, dy) — сдвинуть на месте, move — получить сдвинутую копию;
  • clamp_ip(field) — оставить внутри поля;
  • скорость и гравитация: vy += GRAVITY; y += vy, приземление — bottom = GROUND; vy = 0.