Когда я только начал разрабатывать свой тактический футбольный менеджер, встал вопрос о графике. С тем, что игра будет 2D, я определился сразу. А вот как именно должна выглядеть сцена матча — и особенно поле — предстояло решить.
Всё, что я расскажу в этой статье, основано на моём личном опыте. Надеюсь, читатель не сочтёт это саморекламой, а воспримет как живой пример из практики. Если захотите узнать о проекте подробнее — ссылка на другую статью будет в конце.
1. Почему изометрия?
Недолго думая, я пришёл к выводу: чтобы сцена матча выглядела интересно и выигрышно, нужно использовать изометрию. Сочетание пиксель‑арта с изометрией при должном подходе даёт отличный результат.
Коротко об изометрии: это проекция с соотношением сторон 2:1 — стандарт для многих игр.
|
Тип проекции |
Соотношение |
Угол |
|---|---|---|
|
Симметрия |
1:1 |
45° |
|
Изометрия |
2:1 |
~26.565° |
В случае изометрии на футбольном поле можно разместить больше объектов, сохраняя читаемость и объём.
2. Магия изометрии: плоская картинка с глубиной

Перед нами — 2D‑изображение. Но согласитесь: возникает ощущение глубины, будто мы можем заглянуть в этот мир.
С помощью изометрии можно создать целый мир со всеми деталями — и для этого не нужен 3D. Это как мастерство живописца: хорошая работа со светотенью и цветом заставляет воображение зрителя дорисовывать объём. А что ещё нужно для успеха, если не удивление и вовлечённость?
3. Как я разбивал поле на клетки (билинейная интерполяция)
На экране изометрическое поле выглядит как трапеция. Задача — разделить эту трапецию на равные клетки, которые в «реальности» (в игровом мире) были бы одинаковыми прямоугольниками.
Для этого я использую билинейную интерполяцию.
3.1. Сетка на поле
У поля есть 4 угла:
-
A1 — левый верхний
-
A2 — правый верхний
-
B1 — левый нижний
-
B2 — правый нижний
Каждая клетка задаётся координатами (u, v), где:
-
u— положение по горизонтали (0 — левый край, 1 — правый) -
v— положение по вертикали (0 — верх, 1 — низ)
3.2. Формула
Для любой точки с координатами (u, v):
верхняя_точка = A1 * (1-u) + A2 * uнижняя_точка = B1 * (1-u) + B2 * uрезультат = верхняя_точка * (1-v) + нижняя_точка * v
Или одной строкой:
точка = (A1*(1-u) + A2*u)*(1-v) + (B1*(1-u) + B2*u)*v
3.3. Как это работает
|
Что делаем |
Что получаем |
|---|---|
|
Берём |
Находим точку на верхней и нижней границах поля |
|
Берём |
Находим точку между этими границами |
|
В итоге |
Получаем координаты любой клетки на поле |
Метод даёт ровную сетку, работает с любой трапецией и не требует сложных вычислений.
Пример использования:
-
Чтобы найти центр поля, берём
u = 0.5,v = 0.5. Формула вернёт координаты центра. -
Чтобы найти левую верхнюю клетку (если поле поделено на 4 части), берём
uот 0 до 0.5,vот 0 до 0.5.
3.4. Код Godot
extends Node2D@export var cols: int = 2@export var rows: int = 2var corners = []func _ready():# Углы поляcorners = [Vector2(0, 0), # A1 - левый верхнийVector2(4, 0), # A2 - правый верхнийVector2(4, 2), # B2 - правый нижнийVector2(0, 2) # B1 - левый нижний]var field_center = get_point_on_field(0.5, 0.5)print("Центр поля: ", field_center)for row in rows:for col in cols:var center = get_cell_center(col, row)print("Клетка [", col, ",", row, "] центр: ", center)func get_point_on_field(u: float, v: float) -> Vector2:var top = corners[0].lerp(corners[1], u)var bottom = corners[3].lerp(corners[2], u)return top.lerp(bottom, v)func get_cell_center(grid_x: int, grid_y: int) -> Vector2:var u = (grid_x + 0.5) / colsvar v = (grid_y + 0.5) / rowsreturn get_point_on_field(u, v)
3.5. Таким образом, мы получаем равномерную сетку, идеально совпадающую с границами изометрического поля

4. Вместо заключения
Если статья показалась вам интересной, а мой проект — достойным внимания, буду рад видеть вас в моём сообществе VK. Именно поддержка помогает авторам доводить свои проекты до конца.
Ссылка на сообщество в VK: Plus3S
Ссылка на статью об игре: Уволился. Делаю компьютерную игру / Хабр
ссылка на оригинал статьи https://habr.com/ru/articles/1064122/