Мне было интересно, как происходят столкновения в некоторых простых гоночных играх для 3d автомобилей (особенно в таких играх, как Outrun 2 / Motoracer).
В классических автомобильных гоночных играх со сложной средой (открытый мир), я думаю, это делается с помощью базовой коробки (для автомобиля) для столкновения самолета (для трассы, зданий и прочего). Все это было бы оптимизировано с помощью некоторых ограничивающих рамок (именно так во многих играх происходит столкновение).
В такой игре, как Outrun 2 / Motoracer, игровой процесс настолько прост, что разработчикам это может и не понадобиться, и все могло бы быть значительно упрощено. Для тех, кто никогда не играет в нее, вот что конкретно:
- Автомобиль / велосипед всегда наклеен на дороге.
- Дорога всегда одинакового размера и имеет очень простую форму.
- Единственная возможность - следовать по этой дороге, невозможно покинуть дорогу или столкнуться с чем-то другим (кроме других автомобилей / мотоциклов, но нам все равно).
- Когда вы сталкиваетесь с дорогой, происходит очень простое аркадное столкновение (автомобиль просто отталкивается от него)
Вот как я думаю, что столкновение (возможно) было сделано:
Весь трек можно считать гигантской кривой Безье. Из этой кривой могут быть сгенерированы дорожные полигоны (с использованием векторов спереди, слева и вверх, сгенерированных из кривой). Другие элементы (например, дома, деревья, ...) также могут быть размещены и выровнены с помощью этого метода.
Затем, чтобы обработать столкновения (и нарисовать машину):
1) Найти ближайшую позицию на 3d-кривой из текущей 3d-позиции автомобиля. Другими словами, преобразуйте положение 3d-автомобиля в положение кривой Безье. Каждое 3d-положение на дороге можно рассматривать как смещение вдоль 3d-кривой ( t
) + боковое смещение ( d
). Проверьте изображение ниже, если оно нечеткое (это 2d пример, но это легко относится к 3d).
когда t = 0, автомобиль находится в начале участка пути, когда t = 1, автомобиль находится в конце. когда d = -1 или 1 автомобиль находится на границе пути, когда d = 0 автомобиль находится в середине дороги
2) выровнять машину на дорогу с использованием t
и d
(очень просто: для любого t
и d
значения я могу получить 3d позиции + вверх / передний / левые векторы). машина теперь наклеена на дорогу
3) проверить боковое смещение d
автомобиля. если значение слишком велико (d > 1)
или слишком низкое, (d < -1)
автомобиль не в пути. просто обрежьте его, чтобы поставить машину в нужное место.
Это также делает 3D-выборку очень простой, просто нарисуйте дорожку от текущей t
позиции автомобиля до t + some_big_enough_value_to_avoid_visible_clipping
.
Или, может быть, я совершенно неправ: было бы намного быстрее и проще просто проверить столкновение автомобиля (ограничивающий прямоугольник) и очень упрощенный набор полигонов, представляющих трек (без зданий и тому подобного). 3D-мир (и полученная в результате модель коллизии) просто генерировались бы раньше с использованием какого-либо стороннего инструмента (больше нет 3D-кривой при запуске игры, просто куча полигонов).
источник
В своем гонщике OpenGL я изначально начинал с использования двух кругов для определения границ трассы, но это выглядело слишком хлопотно. Я просто использую glReadPixel, чтобы прочитать цвет пикселя. Если автомобиль игрока находится над зеленым (травянистым) пикселем, то движение еще более ограничено. Это очень мало влияет на производительность.
источник