Как заставить персонажа прыгать и не проваливаться сквозь стены: вся правда об игровой физике
Узнайте, как работает движение персонажей, прыжки, гравитация и столкновения в играх. Разбираем базовую физику на простых примерах кода — от первого шага до создания плавного геймплея. Идеально для начинающих разработчиков!
Когда мы играем в любимые игры, мы редко задумываемся о том, что стоит за плавным движением персонажа, реалистичными прыжками или столкновениями с препятствиями. А ведь за всем этим скрывается увлекательный мир игровой физики — упрощённой модели реального мира, которую программисты создают с помощью математики и кода.

Основы движения: скорость и позиция
В основе любого движения в игре лежат две простые концепции: позиция объекта и его скорость. Представьте, что у вашего персонажа есть координаты X и Y на экране. Каждый кадр игры (обычно это происходит 60 раз в секунду) мы обновляем эти координаты, добавляя к ним значение скорости.
// Простейшее движение
player.x += player.velocityX;
player.y += player.velocityY;Но в реальных играх всё чуть сложнее. Нам нужно учитывать время между кадрами (deltaTime), чтобы движение было плавным независимо от производительности компьютера:
player.x += player.velocityX * deltaTime;
player.y += player.velocityY * deltaTime;Теперь, если игра работает на 30 или 120 FPS, персонаж будет двигаться с одинаковой скоростью в реальном времени.
Гравитация: что заставляет всё падать
Гравитация в играх — это постоянное ускорение, направленное вниз. В каждом кадре мы добавляем небольшое значение к вертикальной скорости объекта, создавая эффект падения:
const GRAVITY = 0.5;
// В каждом кадре
player.velocityY += GRAVITY;
player.y += player.velocityY;
// Проверяем, не упал ли персонаж на землю
if (player.y >= ground.y) {
player.y = ground.y;
player.velocityY = 0;
player.isOnGround = true;
}Интересно, что в большинстве игр гравитация намного сильнее реальной физической. Это делает геймплей более динамичным и отзывчивым. Марио, например, падает в четыре раза быстрее, чем это было бы в реальности!
Прыжки: импульс и управление в воздухе
Прыжок — это просто мгновенное изменение вертикальной скорости в отрицательную сторону (вверх). Когда игрок нажимает кнопку прыжка, мы устанавливаем velocityY в отрицательное значение, и гравитация постепенно замедляет подъём, разворачивает персонажа и заставляет падать обратно.
function jump() {
if (player.isOnGround) {
player.velocityY = -12; // Сила прыжка
player.isOnGround = false;
}
}Но простой прыжок может казаться «деревянным». В хороших платформерах используются дополнительные техники: прыжок переменной высоты (чем дольше держишь кнопку, тем выше прыгаешь), «койот-тайм» (можно прыгнуть ещё долю секунды после того, как сошёл с платформы) и контроль в воздухе (небольшая возможность управлять персонажем во время полёта).
// Прыжок переменной высоты
function updateJump() {
if (!jumpButtonHeld && player.velocityY < 0) {
player.velocityY *= 0.5; // Быстрее прекращаем подъём
}
}Коллизии: как объекты узнают о столкновении
Коллизии — это проверка того, пересекаются ли два объекта в пространстве. Простейший способ — использовать прямоугольные границы (bounding boxes). Два прямоугольника пересекаются, если их стороны перекрываются:
function checkCollision(rect1, rect2) {
return rect1.x < rect2.x + rect2.width &&
rect1.x + rect1.width > rect2.x &&
rect1.y < rect2.y + rect2.height &&
rect1.y + rect1.height > rect2.y;
}Но обнаружить коллизию — это только половина дела. Нужно ещё правильно на неё отреагировать. Это называется разрешением коллизии (collision resolution). Самый простой способ — отодвинуть объект назад, чтобы он не пересекался с препятствием:
if (checkCollision(player, wall)) {
// Определяем, с какой стороны произошло столкновение
const overlapX = Math.min(
player.x + player.width - wall.x,
wall.x + wall.width - player.x
);
const overlapY = Math.min(
player.y + player.height - wall.y,
wall.y + wall.height - player.y
);
// Отталкиваем по оси с меньшим перекрытием
if (overlapX < overlapY) {
player.x += player.velocityX > 0 ? -overlapX : overlapX;
player.velocityX = 0;
} else {
player.y += player.velocityY > 0 ? -overlapY : overlapY;
player.velocityY = 0;
}
}Продвинутые концепции
Когда вы освоите базовую физику, откроется целый мир возможностей. Можно добавить трение, которое замедляет объекты со временем. Можно реализовать упругие столкновения, где объекты отскакивают друг от друга с учётом их массы и скорости. Можно создать систему частиц для эффектов вроде дыма, искр или брызг воды.
Многие современные движки предоставляют готовые физические системы: Unity использует PhysX, Godot имеет встроенный физический движок, а для веб-разработки есть Matter.js и Cannon.js. Но понимание базовых принципов поможет вам эффективно использовать эти инструменты и решать нестандартные задачи.
Практические советы
Начните с простого: создайте квадратик, который падает и может прыгать. Затем добавьте платформы и коллизии. Экспериментируйте с константами — меняйте силу гравитации, высоту прыжка, скорость движения. Вы удивитесь, насколько сильно небольшие изменения влияют на ощущение от игры.
Игровая физика не обязана быть реалистичной — она должна быть весёлой и предсказуемой. Angry Birds, например, полностью игнорирует сопротивление воздуха, потому что так играть интереснее. Ваша задача как разработчика — найти баланс между правдоподобностью и геймплеем.
Хотите погрузиться глубже в разработку игр и научиться создавать собственные проекты с нуля?
В Кодике мы подготовили практические курсы по программированию, где вы пройдёте путь от основ до создания полноценных игр. Изучите JavaScript, Python, Lua и многое другое в удобном формате с пошаговыми объяснениями.
А ещё у нас есть крутой телеграм-канал с дружелюбным комьюнити разработчиков! Там мы обсуждаем интересные технологии, делимся опытом, помогаем друг другу с задачами и просто общаемся на темы программирования.
Присоединяйся к нам и расти вместе с единомышленниками! 🚀