问题描述
我正在用 C++ 和 OpenGL 创建一个游戏,并希望敌人向玩家移动.
I'm creating a game in c++ and OpenGL and want an enemy to move towards the player.
让游戏对象向其他游戏对象移动的最佳方法是什么,同时适用于 2D 和 3D 游戏环境?
What is the best method of making game objects move towards other game objects, that works in both 2D and 3D game environments?
更新:
哇谢谢大家的快速回复!
wow thanks everyone for the quick replies!
奇怪的是,当我发布它时,我设法让它工作
strangely enough I managed to get this to work just as I posted it
尽管出于某种原因,我必须将 x 值乘以更多,以使它们与 y 方向的移动速度一样快.
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;
这是它的工作原理 - 如果您将初始向量添加到敌人的位置,它将立即传送到玩家.你显然想让敌人以较慢的速度移动.当你对向量进行归一化时,你使它的大小(本质上是它形成的三角形的斜边)等于 1.所以现在,添加方向向量会使敌人移动一个单位.将 1 个单位乘以敌人的速度,现在它以正确的速度移动.
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.
所有这些也扩展到 3D.您只需要一个 z 组件.
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.
这是我会做的:
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 > 敌人 Y) 等部分.
You'll notice that by removing the abs() I've also managed to remove the if(playerY > enemyY), etc parts.
这篇关于游戏敌人向玩家移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!