физика игры — перемещение по 2D вектору (защита башни) в переполнении стека

Я пишу простую защиту башни и немного застрял там, где моя башня должна стрелять по врагу.

С этим кодом:

void Bullet::move(int x, int y, int speed)
{

Punkt delta = {(x + speed) - this->x, (y + speed) - this->y};
if (abs(delta.x) > 1 && abs(delta.y) > 1)
{
this->x += delta.x / this->speed;
this->y += delta.y / this->speed;
}
else
{
this->dead = true;
}
}

Где аргументы метода — целевая позиция и скорость. Он должен перемещать пулю вдоль вектора, пока не достигнет цели, но вектор меняется, потому что цель движется. Пока пуля заканчивается вот так (черный — это башня, синий — это пуля, а красный — враг)

ошибка

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

4

Решение

Разумное решение этой проблемы, которое я видел ранее, заключается в следующем:

  1. Постарайтесь предсказать, где будет хорошая точка столкновения для пули и врага. Наивным подходом было бы сделать ваш прогноз просто текущей позицией противника.
  2. Стреляйте в пулю в предсказанном положении
  3. Когда пуля достигнет предполагаемой позиции, заставьте пулю исчезнуть, воспроизведите анимацию урона и уменьшите здоровье врага — независимо от того, действительно ли пуля попадет

Таким образом, если вы достаточно умны со своей математикой, это будет хорошо выглядеть. Но в остальном игра все равно будет работать правильно.

Этот подход также более надежен, если враги могут изменять скорость (например, они замедляются из-за особой местности или башни с эффектом области) после того, как вы обстреляете их.

3

Другие решения

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

2

Хорошо, я немного заглянул на форумы gamedev и нашел решение (которое мне даже удалось понять). Все дело в правильном расчете (как все говорили, было необходимо преобразовать в float). Вот код для ленивых:

float dx = x - this->x;
float dy = y - this->y;
float dx2, dy2;
float distance;
float vx, vy;

distance = sqrt(dx * dx + dy * dy);
dx2 = dx / distance;
dy2 = dy / distance;

vx = dx2 * this->speed;
vy = dy2 * this->speed;

if (distance > 10) // 10 is hitbox size
{
this->x += vx; // still float, its converted to int when applying to surface
this->y += vy;
}
else
{
this->dead = true;
}
0
По вопросам рекламы [email protected]