7.FPS游戏自瞄透视之准星算法
7.FPS游戏自瞄透视之准星算法任鸟飞逆向 任鸟飞逆向 知道了准星的变化规律: 1.准星水平位置摇摆角正北是π,逆时针逐渐减小,正南是0,继续逆时针减小到正北为-ππ和-π重叠(正北方向Y轴逐渐增加,正东方向X轴逐渐增加) 2.准星高度位置俯冲角正上方是0.5π,正下方是-0.5π 我们就要为其写瞄准的算法了。假设人物的坐标是:人物.fX,人物.fY,人物.fZ 目标的坐标是:怪物X,怪物Y,怪物Z。 首先我们写准星水平位置摇摆角这个只考虑X,Y的平面即可不存在高度的问题我们把坐标系分成四个象限来分别计算,理论上是可以统一计算的,但是我们为了更多没有数学基础的同学也能看懂,把其分层四种可能计算更容易理解 ①如果怪物X > 人物.fX 并且 怪物Y > 人物.fY那么怪物处在第一象限也就是我们的东北方 图中角a 根据正切公式等于 atan2(怪物Y-人物.fY,怪物X-人物.fX)返回值为-π到π,图中第一象限范围内 就是返回值 从 π/2 到 0 ,顺时针减少而我们朝向在第一象限是 -π 到 -π/2顺时针增加的我们要把我们得到的角度换算成他的变化规律 才能正确表示准星位置所以第一步我们就要对角度取负让其变化方向一致 都为顺时针增加- atan2(怪物Y-人物.fY,怪物X-人物.fX) 的变化范围就成了 -π/2 到 0 顺时针增加但是范围还是有差别那么第二步,加上偏差的-π/2使其变化规律相同 - atan2(怪物Y-人物.fY,怪物X-人物.fX) -π/2这样就可以自动瞄准了。 ②如果怪物X < 人物.fX 并且 怪物Y > 人物.fY那么怪物处在第二象限也就是我们的西北方 角度依然等于 atan2(怪物Y-人物.fY,怪物X-人物.fX)图中第二象限范围内 返回值 从 0 到 π/2 ,顺时针增加第一步,和我们的范围 π/2 到 π 顺时针增加变化方向一致,不需要取负第二步,偏差π/2加上即可最终atan2(怪物Y-人物.fY,怪物X-人物.fX)+π/2 ③如果怪物X < 人物.fX 并且 怪物Y < 人物.fY那么怪物处在第三象限也就是我们的西南方 角度依然等于 atan2(怪物Y-人物.fY,怪物X-人物.fX)图中第三象限范围内 返回值 从 π/2到0 ,顺时针减少第一步,和我们的范围 0到 π/2 顺时针增加变化方向不一致,取负使其一致-atan2(怪物Y-人物.fY,怪物X-人物.fX)变成 -π/2 到0 顺时针增加第二步,偏差π/2加上即可最终-atan2(怪物Y-人物.fY,怪物X-人物.fX)+π/2 ④如果怪物X > 人物.fX 并且 怪物Y < 人物.fY那么怪物处在第四象限也就是我们的东南方 角度依然等于 atan2(怪物Y-人物.fY,怪物X-人物.fX)图中第四象限范围内 返回值 从 0 到π/2 ,顺时针增加第一步,和我们的范围-π/2都0顺时针增加变化方向一致,不用取负第二步,偏差 -π/2加上即可最终atan2(怪物Y-人物.fY,怪物X-人物.fX)-π/2 然后我们写准星高度位置俯冲角道理一样的,不过是分为抬头还是低头不过这次 求正切角度的2个边不再是 怪物Y-人物.fY和怪物X-人物.fX而是 怪物Z-人物.fZ 和 水平距离了水平距离 = sqrt((怪物X-人物.fX)*(怪物X-人物.fX)+(怪物Y-人物.fY)*(怪物Y-人物.fY));抬头情况下俯视角 = atan2(怪物Z-人物.fZ,水平距离);低头情况下俯视角 =- atan2(人物.fZ-怪物Z,水平距离); 总结代码如下:void Call_自动瞄准(FLOAT 怪物X,FLOAT 怪物Y,FLOAT 怪物Z){T人物属性 人物;人物.初始化();FLOAT 水平角;if (怪物X > 人物.fX && 怪物Y > 人物.fY)//第一象限{水平角=(FLOAT)(- atan2(怪物Y-人物.fY,怪物X-人物.fX)-3.1415926/2);}if (怪物X < 人物.fX && 怪物Y > 人物.fY)//第二象限{水平角=(FLOAT)(atan2(怪物Y-人物.fY,人物.fX-怪物X)+3.1415926/2);}if (怪物X < 人物.fX && 怪物Y < 人物.fY)//第三象限{水平角=(FLOAT)(3.1415926/2-atan2(人物.fY-怪物Y,人物.fX-怪物X));}if (怪物X > 人物.fX && 怪物Y < 人物.fY)//第四象限{水平角=(FLOAT)(atan2(人物.fY-怪物Y,怪物X-人物.fX)-3.1415926/2);} FLOAT 俯视角;FLOAT 水平距离;水平距离 = sqrt((怪物X-人物.fX)*(怪物X-人物.fX)+(怪物Y-人物.fY)*(怪物Y-人物.fY));if (怪物Z > 人物.fZ){俯视角 = atan2(怪物Z-人物.fZ,水平距离);}if (怪物Z < 人物.fZ){俯视角 = 0 - atan2(人物.fZ-怪物Z,水平距离);} DWORD 模块句柄 = (DWORD)GetModuleHandleA("Crossout.exe");*(FLOAT*)(模块句柄 + Base_XY朝向基地址) = 水平角; //计算出来的朝向值 写入内存*(FLOAT*)(模块句柄 + Base_Z朝向基地址) = 俯视角; //计算出来的朝向值 写入内存 }逆向交流qun:453769015
感谢大佬分享
页:
[1]