I'm creating a game in c++ and OpenGL and want an enemy to move towards the player.
What is the best method of making game objects move towards other game objects, that works in both 2D and 3D game environments?
UPDATE:
wow thanks everyone for the quick replies!
strangely enough I managed to get this to work just as I posted it
although for some reason i have to multiply the x values by more to get them to move as fast as the y direction.
anyone have any ideas why? or if what I'm doing is wrong/bad
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))));
}
}
Create a vector in the direction that you want the enemy to move. That's easy:
dir.x = player.x - enemy.x;
dir.y = player.y - enemy.y;
Now normalize this vector. That means divide the terms by the magnitude (the hypotenuse) of the vector.
hyp = sqrt(dir.x*dir.x + dir.y*dir.y);
dir.x /= hyp;
dir.y /= hyp;
Now you just need to add that vector to the enemy's position, multiplied by the speed you want the enemy to move:
enemy.x += dir.x*speed;
enemy.y += dir.y*speed;
Here's how it works - if you add that initial vector to the enemy's position it will instantly be transported to the player. You obviously want to enemy to move at a slower speed. When you normalize the vector, you make it's magnitude (essentially the hypotenuse of the triangle it forms) equal to 1. So now, adding the direction vector moves the enemy by one unit. Multiply that 1 unit by the enemy's speed, and now it's moving at the correct speed.
Edit: all of this extends to 3D as well. You just need a z-component.
Further edits to comment on your code:
You are doing a lot of extra work. You have enough information once you calculate the hypotenuse to move the enemy towards the player. You don't need to use any trig at all - see my code above. You are also calculating (sort of) the magnitude twice:
float hypotenuse = sqrt((xDistance * xDistance) + (yDistance * yDistance));
...
(playerX - enemyX)*(playerX - enemyX)+(playerY - enemyY)*(playerY - enemyY)
The second time it's the distance squared which is a nice optimization, but unnecessary here because you've already calculated the distance and the distance squared.
Here's what I would do:
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);
}
You'll notice that by removing the abs() I've also managed to remove the if(playerY > enemyY), etc parts.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With