Игровой враг движется к игроку

Я создаю игру на С++ и OpenGL и хочу, чтобы противник двигался к игроку.

Каков наилучший способ сделать игровые объекты движущимися к другим игровым объектам, которые работают как в 2D, так и в 3D игровых средах?

UPDATE:

wow благодарит всех за быстрые ответы!

Как ни странно, мне удалось заставить это работать так, как я его разместил

хотя по какой-то причине мне нужно умножить значения x больше, чтобы заставить их двигаться так же быстро, как направление y.

У кого-нибудь есть идеи, почему? или если я делаю неправильно/плохой

float playerX = player.getXPos();
float playerY = player.getYPos();
float enemyX = XPos-*xscroll;
float enemyY = YPos-*yscroll;

glPushMatrix();

glTranslatef(enemyX, enemyY, 0.0);
glColor3f(1.0,0.0,0.0);
    glBegin(GL_POLYGON);
        glVertex2f(-40,40);
        glVertex2f(-40,-40);
        glVertex2f(40,-40);
        glVertex2f(40,40);
    glEnd();

glPopMatrix();


float xDistance = abs(playerX-enemyX);
float yDistance = abs(playerY-enemyY);

if((playerX - enemyX)*(playerX - enemyX)+(playerY - enemyY)*(playerY - enemyY) < 400*400){
    float heading = asin(xDistance/yDistance);

    if(playerY > enemyY){
        YPos += timeFactor*(200*(sin((90+heading)*(PI/180.0f))));
    }else{
        YPos += -(timeFactor*(200*(sin((90+heading)*(PI/180.0f)))));
    }

    if(playerX > enemyX){
        XPos += -(timeFactor*(10000*(cos((90+heading)*(PI/180.0f)))));
    }else{
        XPos += timeFactor*(10000*(cos((90+heading)*(PI/180.0f))));
    }
}

Ответ 1

Создайте вектор в том направлении, в котором вы хотите, чтобы противник двигался. Это легко:

dir.x = player.x - enemy.x;
dir.y = player.y - enemy.y;

Теперь нормализуем этот вектор. Это означает деление членов на величину (гипотенузу) вектора.

hyp = sqrt(dir.x*dir.x + dir.y*dir.y);
dir.x /= hyp;
dir.y /= hyp;

Теперь вам просто нужно добавить этот вектор в положение врага, умноженную на скорость, которую вы хотите, чтобы противник двигался:

enemy.x += dir.x*speed;
enemy.y += dir.y*speed;

Здесь, как это работает - если вы добавите этот исходный вектор в позицию противника, он мгновенно будет перенесен на плеер. Вы, очевидно, хотите, чтобы враг двигался с меньшей скоростью. Когда вы нормализуете вектор, вы делаете его величину (по существу, гипотенузу треугольника, который она образует) равна 1. Итак, теперь добавление вектора направления перемещает противника на единицу. Умножьте 1 единицу на вражескую скорость, и теперь она движется с правильной скоростью.

Изменить: все это распространяется и на 3D. Вам просто нужен z-компонент.

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

Вы делаете много дополнительной работы. У вас достаточно информации, как только вы вычислите гипотенузу, чтобы переместить врага в сторону игрока. Вам вообще не нужно использовать какой-либо триггер - см. Мой код выше. Вы также вычисляете (вид) величину в два раза:

float hypotenuse = sqrt((xDistance * xDistance) + (yDistance * yDistance));
...
(playerX - enemyX)*(playerX - enemyX)+(playerY - enemyY)*(playerY - enemyY)

Во второй раз это квадрат расстояния, который является хорошей оптимизацией, но ненужным здесь, потому что вы уже рассчитали расстояние и квадрат расстояния.

Вот что я буду делать:

float xDistance = playerX-enemyX;
float yDistance = playerY-enemyY;
float hypotenuse = sqrt((xDistance * xDistance) + (yDistance * yDistance));

if(hypotenuse < 400){

        YPos += timeFactor*200*(yDistance/hypotenuse);
        XPos += timeFactor*200*(xDistance/hypotenuse);
}

Вы заметите, что, удалив abs(), мне также удалось удалить элементы if (playerY > enemyY) и т.д.

Ответ 2

Используйте vectors. Это очень просто и точно, как это делают настоящие игры.

Если ваш игрок находится в положении 10, 10 (предположим, что это 2D-пространство), а ваш враг был равен 20, 10. Вектор от игрока к врагу:

Player - Enemy

или

(10, 10) - (20, 10) = -10, 0

Нормализация этого вектора дает вам единичный вектор или направление. Который в этом случае равен -1, 0. Множественный единичный вектор (который помнит направление) скалярным значением каждого кадра, а враг будет двигаться к игроку. Что происходит, когда оно доходит до вас;)

Ответ 3

Позиция игрока - точка 1. Позиция врага - точка 2. Сначала вам нужно найти разницу между x1 и x2 и y1 и y2 (я буду называть эти xd и yd). Затем вы можете получить угол между двумя точками, выполнив theta = atan (yd/xd). Теперь вы можете получить новые x и y (которые я назову x3 и y3), используя угол и расстояние, которое вы хотите перемещать, где x3 = (d) (cos (theta)) и y3 = (d) (грех (тета)). Переместите враг на (x3, y3).

d - скорость, которую противник движется за обновление. Вам, возможно, придется возиться со знаками, чтобы правильные направления (т.е. Если враг движется в правильном направлении x, но не в правильном направлении y, то измените знак на y).

Надеюсь, это поможет!

Ответ 4

Здесь вам нужен "алгоритм поиска пути". На ясном игровом поле вы можете следовать прямой линии к цели. Однако, с препятствиями на пути, вы должны дать ему ИИ, чтобы решить наилучший путь, или если это возможно.

Поиск в codeproject.com даст несколько статей о поиске путей.