zl程序教程

您现在的位置是:首页 >  Java

当前栏目

FPS游戏:方框绘制算法分析

2023-02-18 16:44:41 时间

方框透视的原理是通过读取游戏中已知坐标数据,并使用一定算法将自己与敌人之间的距离计算出来,结合GDI绘图函数在窗体上直接绘制图形,直到现在这种外挂依然具有极强的生命力,原因就是其比较通用,算法固定并能够应用于大部分的FPS游戏中。接下来我们将具体分析计算方框的思路,以及实现这些方框绘制算法。

GitHUB开源地址: https://github.com/lyshark/Counter-Strike-Cheat

第一象限求角: 假设敌人在第一象限,求鼠标指向与敌人之间的夹角b,可以使用反正切求导。

我们知道自己与敌人的相对(X,Y)距离,可以使用反正切公式求出a角的度数。而我们最终的目的是要求出我们的鼠标指向与敌人之间的夹角b,此时我们可以通过已知的鼠标角度C减去a既可得到b的角度。

第二象限求角: 假设敌人在第二象限,而我们的鼠标依然指向在第一象限,求敌人与X轴之间的夹角度数。

如上图:由于(X,Y)(黑色)是已知条件,我们可以通过X比Y求反正切,即可得到a角的度数,然后与90度相加,即可求出敌人当前坐标位置与X轴之间的夹角度数。

第三四象限: 敌人在第三与第四象限与上图差不多,最终目的就是求敌人的位置与X轴之间的夹角,第三象限应该加180度,第四象限加上270度数。这里就不罗嗦了,很简单的东西。

另外4种特殊情况: 如果敌人在第一象限且与X轴重合,那么敌人与X轴为之间的夹角度数必然为零度,同理如果与Y轴重合的话,那么X轴与敌人之间的夹角度数为90度,以此类推就是这四种特殊情况。

上方的4条象限与特殊情况,如果展开的话一共是8种不同的情况,如下代码就是这八种不同情况,调试下面的这段代码会发现一个缺陷,那就是当我们绕着敌人转圈时,偶尔会出现一个大于180度的角度,这又是两种非常特殊的情况。

特殊情况: 当敌人在第四象限且鼠标角度依然在指向第一象限的情况下,则会出现大于180度的角。

如上图:我们的目标是求鼠标角度与敌人之间的夹角度数,而此时的鼠标指向第一象限,而敌人却在第四象限上,我们用360度减去e角度(e = 敌人坐标与x轴之间的夹角度数),即可得到K角度,用K角度加上M角度,即可得到鼠标与敌人之间的夹角度数,另一种特殊情况敌人与鼠标角度调换位置求角,最终代码如下:

FOV视场角度: 摄像机的作用就是,移动游戏中的场景,并将其投影到二维平面,显示给玩家。

如上图:摄像机与屏幕之间的夹角统称为视场角,游戏中的准星位置到屏幕的边缘是FOV的一半,以屏幕分辨率1024x768为例,当FOV为90度时,则准心与屏幕的垂线构成45度等腰直角三角形,此时的摄像机到屏幕的距离就是一半屏幕长度(1024/2 = 512)的大小。

三维横坐标转屏幕X坐标: 将三维矩阵中的敌人坐标数据,转换为屏幕的X坐标。

如上图:我们需要求出敌人位置的坐标数据,可以使用 (x/y) x (1024/2) 最后还需要加上P的长度,由于窗口的总长度是1024那么我们可以直接除以2得到另一半的长度(512),将敌人位置与另一半长度相加就是敌人投射在屏幕上的X坐标,但是此时我们并不知道(X,Y)的长度,所以需要先求出(X,Y) 如下图所示。

上图中:我们需要求出(X,Y)的距离,此时我们已经知道了M和C的长度,则此时我们可以直接使用勾股定理M的平方 + C的平方 (开方)= Z,得到Z之后,通过 sin a = (x/z) => sin a * z = X 此时我们已经得到的X的长度,接着 cos a =(y/z) => cos a * z = Y 此时我们也得到了Y的长度,最后 (x/y) x 512 + 512 即可得到敌人位置,投射到屏幕上的X坐标。

三维纵坐标转屏幕Y坐标: 三维横坐标搞懂了,这个纵坐标就更简单了,如下图:

上图中:通过tan公式即可推导出d与c的距离,然后将d与c的长度相加,即可得到鼠标指向与敌人位置之间的距离,然后再加上屏幕高度的一半,本游戏屏幕高度为768,所以要加上384即可。

最终屏幕横坐标与纵坐标的转换算法如下所示,最后一点代码不搞了!要搬砖去了!

最后的透视效果如下,此处游戏屏幕必须为1024x768,三维坐标转屏幕坐标算法中已经写死了,其他屏幕尺寸需要自行调整代码中的比值关系与相应数值。