Игровой враг движется к игроку
Я создаю игру на С++ и 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 даст несколько статей о поиске путей.