Движение объекта в 2D: физика, формула и векторное управление
Разработка игр и симуляторов на Canvas JavaScript требует понимания базовой физики движения. Когда у вас есть объект (космический корабль, спрайт) в прямоугольной системе координат с позицией x и y, а также управление через WASD, ключевой вопрос - как правильно изменять координаты, чтобы движение было реалистичным. В этой статье мы разберём формулы перемещения, учёт ускорения и скорости, а также работу с векторами направления и вращения.
Основная формула движения с ускорением
Для движения объекта с постоянным ускорением и ограничением по скорости используйте классическую кинематическую модель. Каждый кадр (tick) обновляйте скорость и позицию:
- Скорость:
velocity += acceleration * direction * deltaTime - Позиция:
position += velocity * deltaTime
Где direction - нормализованный вектор направления (единичной длины), полученный из нажатых клавиш. Например, при нажатии W вектор (0, -1), при D (1, 0). Ускорение и скорость - скалярные величины, которые вы ограничиваете максимальным значением. В коде это выглядит так:
// Псевдокод обновления каждый кадр
let accel = 0.5; // ускорение
let maxSpeed = 10;
let friction = 0.98; // трение для остановки
// Обновление скорости
if (isMoving) {
speed += accel * dt;
if (speed > maxSpeed) speed = maxSpeed;
} else {
speed *= friction;
}
// Обновление позиции
x += dirX * speed * dt;
y += dirY * speed * dt;Учёт вращения и вектора направления носа
Если объект может вращаться, у вас появляются два вектора: вектор текущего движения (куда объект фактически летит) и вектор направления носа (куда смотрит объект). Их не нужно складывать - вместо этого используйте скалярное произведение (dot product) для определения, ускоряться или тормозить:
- Dot product > 0: нос и движение сонаправлены - ускоряем.
- Dot product < 0: нос и движение противоположны - тормозим (или разворачиваем).
Формула: dot = (moveDir.x * noseDir.x + moveDir.y * noseDir.y). Если значение положительное, тяга двигателя добавляется к скорости; если отрицательное - скорость уменьшается.
Пример реализации поворота и тяги
// Вектор движения (нормализованный)
let moveDir = {x: Math.cos(angle), y: Math.sin(angle)};
// Вектор текущей скорости (нормализованный)
let velDir = {x: vx / speed, y: vy / speed};
// Скалярное произведение
let dot = moveDir.x * velDir.x + moveDir.y * velDir.y;
if (dot > 0) {
// Ускоряемся
speed += thrust * dt;
} else {
// Тормозим
speed -= brake * dt;
}
// Обновляем позицию
x += vx * dt;
y += vy * dt;Формула точки на окружности для поворота
Чтобы повернуть объект на заданный угол, используйте формулу точки на окружности. Если центр объекта (x0, y0), а нос находится на расстоянии r от центра, новые координаты носа после поворота на угол θ:
newX = x0 + r * Math.cos(θ);
newY = y0 + r * Math.sin(θ);Это пригодится для визуализации направления или для прицеливания.
Практические советы для Canvas JS
- Всегда нормализуйте векторы направления, чтобы скорость не зависела от количества одновременно нажатых клавиш.
- Используйте
deltaTimeдля независимости от частоты кадров (FPS). - Ограничивайте скорость через
Math.min(speed, maxSpeed). - Для плавного торможения применяйте трение:
speed *= 0.98каждый кадр.
Эти формулы и подходы - база для любой 2D-игры с управлением WASD. Если вы забыли старый код, просто восстановите логику по этим принципам: вектор направления, ускорение, ограничение скорости и скалярное произведение для поворота.