Я работаю над гоночной игрой для школьного проекта.
Использование Visual Studio 10 Pro и Irrlicht.
Извините за плохую грамматику>.>, И это мой первый вопрос, поэтому я не уверен, что все сделано правильно.
Как я хочу, чтобы это работало, я делаю путевые точки в разных точках трассы,
а затем я запускаю проверку путевой точки, чтобы проверить, не прошла ли машина ее следующая путевая точка (следующая, которую ей «нужно» проехать), если да, то она обновляет следующую путевую точку, иначе ничего.
Я надеюсь, что это сработает, я делаю вектор из n в n + 1, затем нахожу вектор, перпендикулярный первому в n. Затем я вижу, находится ли объект впереди или позади этого вектора.
Я нашел Gamedev.net форум это помогло мне сделать эту функцию:
void Engine::checkWaypoint(Vehicle* vehicle)
{
btVector3 vector = waypoints[vehicle->nextWaypoint];
// n
btVector3 nextVector = waypoints[vehicle->nextWaypoint + 1];
// n+1
vector = nextVector - vector;
// First vector
btVector3 pos = btVector3(vehicle->position.X,vehicle->position.Y,vehicle->position.Z);
float product = vector.dot(pos - waypoints[vehicle->nextWaypoint]);
// positiv = before, negative = behind
if(product < 0)
vehicle->nextWaypoint += 1;
}
Текущие ошибки с этим:
Обновляет следующую точку маршрута более, чем одну, не проходя новую точку.
Когда он достигает конца и сбрасывается, он прекращает срабатывание на первых путевых точках.
Итак, мои вопросы:
Это хороший способ сделать это?
Я правильно сделал?
Ваш код измеряет, насколько далеко игрок проходит по вектору от текущей путевой точки до следующей. Однако, если векторы для двух последовательных сегментов расположены (например) под прямым углом, алгоритм может пропускать несколько точек маршрута одновременно. (т. е. если вы проведете линию через следующую путевую точку, она может продолжаться прямо по середине дороги, что означает, что игрок мог идти назад и вперед по ней, двигаясь к этой путевой точке).
Может сработать некоторый ограничивающий объем, либо расстояние до путевой точки (убедитесь, что она меньше, чем двукратная ширина дороги), либо расстояние до вектора, который вы рассчитали между точками.
(или вы можете просто добавить больше точек)
Что касается того, почему это не работает, когда вы на коленях, кажется, вы просто добавляете одну к путевым точкам, чтобы найти следующую. Вы должны сделать этот расчет по модулю:
next_waypoint = (vehicle->nextWaypoint + 1) % num_waypoints;
Обычно в гоночной игре вы должны быть на контрольно-пропускном пункте чтобы это было подтверждено: вы просто проверяете, что машина находится достаточно близко от контрольно-пропускного пункта. Итак, я думаю, что следующий псевдокод будет действительным:
if( car is_near current_checkpoint )
current_checkpoint = current_checkpoint->next_checkpoint;
is_near: return distance(car, current_checkpoint) < some value
Для проверки расстояния вы можете либо использовать простую форму круга (как показано в псевдокоде), либо вы можете проверить, попадает ли автомобиль в ограничивающую рамку контрольной точки (или в рамку, расположенную внутри контрольной точки); зависит от того, как сделаны ваши контрольные точки.
Или же, вы можете сделать кривую, сделанную всеми линиями от контрольных точек до их последователей, а затем найти ближайшую линию, где она находится, из которой вы можете найти следующую контрольную точку. Пример:
o--o
/ \
o-----------------o \
/ \ <-- your track: S = start
/ o E = end
/ o---o X / o = checkpoint
S / \ . / X = car
/ o------.----o
/ ^
E--o |
closest road from the car
Неудобно: результаты могут отличаться в зависимости от кривизны дорог.
Я советую вам использовать первый метод, который я описал.
Обнаружил, что мой оригинальный код работает, проблема была с путевыми точками.
Делали путевые точки легко видимыми, и все они были слишком близко друг к другу, поэтому коде повторялся много раз в одних и тех же местах.
Поэтому я увеличил расстояние между путевыми точками и превратил их в трек, и все стало работать так, как я этого хотел.