Окно и система координат
Прежде чем рисовать героев, нужно открыть окно и понять, в какой системе координат мы вообще находимся. Спойлер: ось Y направлена вниз, и это меняет всё.
Суть: окно Pygame — это сетка пикселей, где (0,0) в левом верхнем углу, X растёт вправо, а Y растёт ВНИЗ. Любая позиция объекта — это пара чисел (x, y) в этой сетке.
Окно игры — это просто прямоугольник из пикселей. Чтобы что-то на нём разместить, нужен адрес каждой точки. В математике в школе ось Y направлена вверх. В компьютерной графике — наоборот, вниз. Это не ошибка и не каприз: так исторически устроены экраны, которые «рисуются» сверху вниз, строчка за строчкой. Привыкнуть нужно один раз, и дальше это станет автоматическим.
Точка (0, 0) — это левый верхний угол окна. Если окно 800 на 600 пикселей, то правый нижний угол — это (799, 599). Хочешь подвинуть объект вправо — увеличиваешь x. Хочешь вниз — увеличиваешь y. Хочешь вверх (например, прыжок) — УМЕНЬШАЕШЬ y. Именно отсюда позже возьмётся «минус» в коде прыжка, и теперь ты не удивишься.
Почему это важно знать до всего остального? Потому что 90% багов новичка в графике — это «герой улетел не туда». Почти всегда причина — перепутанная ось Y или забытый угол отсчёта.
Как работает под капотом
Экран — это двумерный массив пикселей. Pygame хранит «поверхность» (Surface) как сетку, и когда ты говоришь «нарисуй прямоугольник в (100, 50)», движок закрашивает пиксели начиная с этого адреса. Вот карта координат окна:
(0,0) X растёт --> (799,0)
+----------------------------------------------+
| . (100,50) |
Y | |
| | . (400,300) <- центр |
v | |
рас | |
тёт | . (700,500) |
+----------------------------------------------+
(0,599) (799,599)
Чтобы найти центр окна, делим размеры пополам: при окне 800x600 центр — это (400, 300). Это пригодится постоянно: спавн героя по центру, размещение текста, расчёт расстояний.
Создание окна на pygame выглядит так (читаем, не запускаем):
import pygame
pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Моя первая игра") # заголовок окна
center_x = WIDTH // 2 # 400
center_y = HEIGHT // 2 # 300
print("Центр окна:", center_x, center_y)А вот чистая математика координат, которую можно запустить прямо здесь. Посчитаем центр и проверим, попадает ли точка в границы окна — это пригодится, чтобы герой не «убегал» за край:
WIDTH, HEIGHT = 800, 600
def inside_window(x, y):
return 0 <= x < WIDTH and 0 <= y < HEIGHT
center = (WIDTH // 2, HEIGHT // 2)
print("Центр окна:", center)
print("(400, 300) внутри?", inside_window(400, 300))
print("(850, 300) внутри?", inside_window(850, 300)) # вышли за правый край
print("(100, -5) внутри?", inside_window(100, -5)) # вышли вверхПеревод между «школьными» и «экранными» координатами
Иногда удобнее думать в привычной математической системе, где Y растёт вверх, например при расчёте траектории снаряда. В этом случае держи логику в «школьных» координатах, а при отрисовке переводи: экранный_y равен высоте_окна минус математический_y. Этот единственный пересчёт на границе отрисовки избавляет от путаницы внутри расчётов. Такой приём — отделить «мир» от «экрана» — используют даже в больших движках, и называется он преобразованием координат.
Полезно сразу привыкнуть мыслить не пикселями, а долями окна. Если разместить кнопку в точке (WIDTH * 0.5, HEIGHT * 0.8), она останется внизу по центру при любом размере окна. А вот жёсткое (400, 480) сломается, стоит сменить разрешение. Этот принцип — относительное позиционирование — особенно важен, когда твою игру запустят на экранах разного размера. Привыкай считать всё от WIDTH и HEIGHT, и твой интерфейс будет «резиновым» бесплатно.
Частые ошибки
- Думать, что Y растёт вверх — и удивляться, почему «вверх» уводит объект вниз.
- Забыть, что отсчёт с нуля — у окна 800px последний пиксель имеет индекс 799, а не 800.
- Хардкодить 400 и 300 вместо WIDTH//2 — поменяешь размер окна, и всё развалится.
Best practices
- Заводи константы
WIDTHиHEIGHTв начале файла и считай всё относительно них. - Запоминай правило: меньше Y — выше на экране, больше Y — ниже.
- Давай окну осмысленный заголовок через
set_caption— мелочь, а выглядит профессионально.
Итог: окно — это сетка пикселей с началом в левом верхнем углу и осью Y, направленной вниз. Теперь у нас есть «адреса» для всего, что мы будем рисовать.