You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenGL 2D项目中敌人无法朝向玩家移动的技术求助

问题:敌人朝向玩家正常,但移动时反而远离,如何实现正确的追踪移动?

我正在开发一个2D游戏项目,需要实现敌人追踪玩家的功能。目前敌人已经能正确朝向玩家,但移动逻辑出了问题——敌人会朝着远离玩家的方向移动,而不是靠近。

以下是我的相关代码:

玩家绘制代码

//Body
modelMatrix = visMatrix;
modelMatrix *= transform2D::Translate(translateX, translateY);
modelMatrix *= transform2D::Scale(1, 1);
modelMatrix *= transform2D::Rotate(playerAngle);
modelMatrix *= transform2D::Translate(-50, -50);
RenderMesh2D(meshes["square3"], shaders["VertexColor"], modelMatrix);
//Eye1
modelMatrix = visMatrix;
modelMatrix *= transform2D::Translate(translateX, translateY);
modelMatrix *= transform2D::Scale(0.25f, 0.25f);
modelMatrix *= transform2D::Rotate(playerAngle);
modelMatrix *= transform2D::Translate(150, 200);
modelMatrix *= transform2D::Rotate(0);
modelMatrix *= transform2D::Translate(-50, -50);
RenderMesh2D(meshes["square1"], shaders["VertexColor"], modelMatrix);
//Eye2
modelMatrix = visMatrix;
modelMatrix *= transform2D::Translate(translateX, translateY);
modelMatrix *= transform2D::Scale(0.25f, 0.25f);
modelMatrix *= transform2D::Rotate(playerAngle);
modelMatrix *= transform2D::Translate(-150, 200);
modelMatrix *= transform2D::Rotate(0);
modelMatrix *= transform2D::Translate(-50, -50);
RenderMesh2D(meshes["square1"], shaders["VertexColor"], modelMatrix);

敌人绘制代码

//Body
modelMatrix = visMatrix;
modelMatrix *= transform2D::Translate(translateEnemyX, translateEnemyY);
modelMatrix *= transform2D::Scale(1, 1);
modelMatrix *= transform2D::Rotate(enemyAngle);
modelMatrix *= transform2D::Translate(-50, -50);
RenderMesh2D(meshes["border"], shaders["VertexColor"], modelMatrix);
//Eye1
modelMatrix = visMatrix;
modelMatrix *= transform2D::Translate(translateEnemyX, translateEnemyY);
modelMatrix *= transform2D::Scale(0.25f, 0.25f);
modelMatrix *= transform2D::Rotate(enemyAngle);
modelMatrix *= transform2D::Translate(150, 200);
modelMatrix *= transform2D::Rotate(0);
modelMatrix *= transform2D::Translate(-50, -50);
RenderMesh2D(meshes["square2"], shaders["VertexColor"], modelMatrix);
//Eye2
modelMatrix = visMatrix;
modelMatrix *= transform2D::Translate(translateEnemyX, translateEnemyY);
modelMatrix *= transform2D::Scale(0.25f, 0.25f);
modelMatrix *= transform2D::Rotate(enemyAngle);
modelMatrix *= transform2D::Translate(-150, 200);
modelMatrix *= transform2D::Rotate(0);
modelMatrix *= transform2D::Translate(-50, -50);
RenderMesh2D(meshes["square2"], shaders["VertexColor"], modelMatrix);

当前角度计算(朝向正常)

enemyAngle = atan2(translateX - translateEnemyX, translateY - translateEnemyY);

移动逻辑(问题所在)

enemySpeed = 10;
translateEnemyX += enemySpeed * cos(enemyAngle);
translateEnemyY += enemySpeed * sin(enemyAngle);

现在的问题是,敌人朝向玩家是对的,但移动时会远离玩家。请问该如何修正移动逻辑,让敌人正确向玩家移动?


回答

这个问题的核心是**atan2的参数顺序和三角函数对应关系不匹配**,导致移动方向搞反了。我们一步步来解决:

1. 理解atan2的参数顺序

标准的atan2函数定义是atan2(y, x),它计算的是从原点到点(x,y)的向量与x轴正方向的夹角。你当前计算角度时把**x方向的差值(玩家X - 敌人X)**放在了y参数的位置,**y方向的差值(玩家Y - 敌人Y)**放在了x参数的位置,这刚好搞反了。不过因为这个角度适配了你渲染坐标系的旋转规则,所以敌人朝向显示正常,但移动时用cos和sin对应这个角度就会出错。

2. 修正移动逻辑的两种方案

方案一:调整三角函数的对应关系

既然角度计算是适配渲染的,那我们可以直接调整移动时的三角函数使用,交换cos和sin的位置并修正符号:

enemySpeed = 10;
// 交换cos和sin,匹配当前角度的坐标系规则
translateEnemyX += enemySpeed * sin(enemyAngle);
translateEnemyY += enemySpeed * cos(enemyAngle);

方案二:基于向量的移动(更直观推荐)

其实不用纠结三角函数,直接计算敌人到玩家的方向向量,归一化后乘以速度移动,这种方法完全绕开坐标系差异问题,逻辑更清晰:

enemySpeed = 10;
// 计算敌人指向玩家的方向向量
float dirX = translateX - translateEnemyX;
float dirY = translateY - translateEnemyY;
// 计算向量长度(避免除以0的情况)
float distance = sqrt(dirX * dirX + dirY * dirY);
if (distance > 0) {
    // 归一化向量(方向不变,长度变为1)
    dirX /= distance;
    dirY /= distance;
    // 按速度移动敌人
    translateEnemyX += enemySpeed * dirX;
    translateEnemyY += enemySpeed * dirY;
}

这种向量式的移动在2D游戏里非常常用,后续扩展(比如添加障碍物躲避、平滑追踪)也更容易实现。

3. 为什么之前的移动会反向?

你用反序参数计算的enemyAngle,对应的向量和实际需要的追踪方向是错位的,导致cos(enemyAngle)和sin(enemyAngle)给出的移动方向刚好与玩家所在方向相反,所以敌人会越跑越远。

建议优先试试方案二,这种方法出错概率更低,也更符合现代游戏开发的常规思路。

内容的提问来源于stack exchange,提问作者Catalin Ursu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 23:47:43