Симуляция движения и заноса машины в игре на JavaScript

в 8:57, , рубрики: game development, javascript, игры, метки: ,

Нужно было написать игру на JavaScript. Решил остановиться на примитивных гоночках. Когда я овладел принципами вращения и перемещения по HTML5 Canvas появилась следующая проблема: управление автомобилем. Делая эту игру я вспоминал игру Grand Prix Simulator 2 ZX Spectrum, в кторую я играл на компьютере «Байт».

Управление там было следующее:

  • стрелка вверх: газ;
  • стрелка влево: поворот против часовой стрелки;
  • стрелка вправо: поворот по часовой стрелке.

Реализовать это было просто: у машины есть направление в радианах, по нажатию кнопки у неё вызывается событие rotateLeft или rotateRight. Эти методы просто добавляют или вычитают константное значение изменения угла из направления машины.

Но в той игре ещё у машины был занос (поначалу неудобно, но с ним интереснее). И я решил написать какую-нибудь эмуляцию заноса. По сути занос происходит когда сама машина меняет направление, но её движение не меняет направление вместе с ней. Насколько точно нужно воспроизвести движение с точки зрения физики? Я ставил целью сделать такой занос, который будет похож на реальный.

Для начала нужно разделить вектор скорости и направление машины:

this.carDirection — угол, задающий ориентацию машины;
this.linearVelocity — вектор скорости, заданный в декартовых координатах.

Дальше вешаем событие изменения ориентации машины на клавиши поворота. Когда она отличается от направления вектора скорости, то он начинает поворачиваться по направлению машины. Скорость поворота этого вектора задаётся эмпирическим коэффициентом SMOOTHING.

Симуляция движения и заноса машины в игре на JavaScript

Итак, машину понесло. Тепрь нужно проверить удержался ли пилот на трассе. Трасса представляет собой ломаную, участки которой имеют определённую ширину. Эти линии на трассе находятся под каким-то углом. Таким образом задача формулируется следующим образом: нужно проверить попадает ли точка в прямоугольник, расположеный под каким-то углом.
Одним из способов будет перенос системы координат на участок трассы так, чтобы этот участок трассы лежал на одной из осей. Для этого нужно вычесть из координат машины координаты начала отрезка, а затем умножить их на матрицу поворота:

function turnAndTranslate(lineIndex, position) {
    return [
        trace[lineIndex].cos * (position[0] - trace[lineIndex].begin[0]) + 
            trace[lineIndex].sin * (position[1] - trace[lineIndex].begin[1]),
        trace[lineIndex].sin * (- position[0] + trace[lineIndex].begin[0]) + 
            trace[lineIndex].cos * (position[1] - trace[lineIndex].begin[1])
        ];
}

Для матрицы поворота умножить вектор координат на матрицу, которая содержит синус и косинус угла поворота. Чтобы не вычислать тригонометрические функции при каждой проверке они вычисляются только один раз при инициализации карты и сохраняются как коэффициенты для каждого отрезка трассы.

Симуляция движения и заноса машины в игре на JavaScript

Программа сыроватая, но покататься уже можно тут.

Автор: oldHamtick

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js