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

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

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

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


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

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

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

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

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



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

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])
        ];
}


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



Программа сыроватая, но покататься уже можно тут.
Реклама
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее

Комментарии 19

  • НЛО прилетело и опубликовало эту надпись здесь
      +2
      Отлично! Но сыро, очень сыро. Режим «Голливуд» — космос просто! Продолжайте!
        +1
        У вас передний привод, а на гоночных болидах задний.
          +1
          Что-то странное с именами файлов при попытке открыть архив в Ubuntu. Вместо букв вопросы.
            0
            unzip нормально распаковывает
              0
              В макоси тоже самое.
              +1
              Grand Prix, вспоминаю, как играли в эту игру вчетвером на одном спектурме, На одной клавиатуре! Да. Были времена.
                0
                Помоему вы привираете. Система то вообше реагировала более чем на 4 зажатых клавиши?
                  +1
                  www.worldofspectrum.org/infoseekid.cgi?id=0002115
                  Количество игроков — 4. Т.к. действо происходило давно, более 10 лет назад, я могу и немного соврать, но не ради того что бы обмануть, а по забывчивости. Точно не помню, может один кемпстон был на корпусе распаян. А второй вынесли шнуром, и еще двое на клавишах. В этой игре не надо постоянно жать кнопку газа. Так что все возможно. Но точно помню что сидеть вчетвером было очень неудобно, но игра затягивала)
                    0
                    Я поэтому и сказал что не врете, а привираете :) Просто я отчетливо помню как мы играли в NFS еще помоему 3й на разделенном экране вдвоем. И когда зажимали клавиши движения — все было хорошо. Но стоило кому-то зажать 3ю клавишу, то все — система начинала истошно пищять системным спикром и отчаяно отказывалась реагировать на кнопки вообще.
                      +3
                      Спектрум не ПК, клавиатура у него устроена совершенно иначе.
                      Кстати, и на ПК есть клавиатуры с поддержкой 10+ одновременно зажатых клавиш.
                    +2
                    Всё зависит от того, какие именно это клавиши.
                    • НЛО прилетело и опубликовало эту надпись здесь
                      0
                      Я играл в ту версию, в которой три человека. Хотя обычно мы играли с братом вдвоём.
                      +10
                      Воспользуйтесь Github и Github pages. Можно будет смотреть код и играть более естественным образом.
                        +2
                        bmp? wtf?!
                          +5
                          С точки зрения физики ваши формулы, конечно, описывают сферического коня в вакууме. Рекомендую вот эту статью: www.asawicki.info/Mirror/Car%20Physics%20for%20Games/Car%20Physics%20for%20Games.html

                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                        Самое читаемое