来源:互联网
创建射击游戏时经常使用自动跟踪算法。这听起来很高深,但实际上并不是军事科学的垄断;从数学上来说,它意味着求解微分方程。
如果没有一些数学基础,这是很难计算的。但计算机不同。你可以利用计算机极快的计算速度,利用微分的思想,再加上一些简单的三角学知识来做到这一点。
现在,我们先看一下算法的原理,再看图。
由于我们稍后将在演示中使用pygame,因此我们还将使用y 轴向下的坐标系,因为pygame 的坐标系是y 轴向下的。
算法的总体思路就是将时间t划分为足够小的段(比如1/1000,时间片越小越准确),基于上图。每个线段形成一个三角形,如图所示。计算导弹下一个时间片的方向(即a)和行进距离(即vt=|AC|)。然后目标在第二个时间片中移动位置。计算出的值成为第二个时间片,在C点构造一个三角形,在第二个时间片中创建一个新的目标点并计算新的vt,进入第三个时间片,并使用这个Repeat。
假设导弹和目标的初始坐标分别为(x1,y1)和(x,y),并创建直角三角形ABE。这个三角形用来求a的正弦和余弦值。由于vt是自己设定的,所以我们需要计算x和y坐标从A点到C点走了多远。移动值是AD和CD的长度。我们可以将这两者乘以vt cos(a)。 ) 和sin(a) 分别。
计算sin(a) 和cos(a)、正弦和斜率、余弦邻接和斜率。斜边可以使用两点距离公式计算。换句话说:
在那之后
AC 的长度是导弹的速度乘以时间。即|AC|=vt。因此,在这个时间片过去后,导弹应该出现在新位置C。其坐标为:旧点A 的x 增加AD,y 减少CD。
因此,C点的新坐标为:
只要不断重复这个操作就可以了。为了清楚起见,我们将第一个和第二个时间片结合起来。
首先是时间片构造的三角形是ABE。经过一个时间片后,目标从B 点走到D 点。由于导弹现在位于C 点,因此构建并计算了新的三角形CDF。重复这个过程就足够了。事实上,你只需要修正导弹的方向即可。是我们需要研究的问题。
我最近在使用Python的pygame库编写一个小游戏,所以我将使用pygame来演示这种效果。
这是一个非常简单的代码:
导入pygame,系统
从数学导入*
pygame.init()
屏幕=pygame.display.set_mode((800,700),0,32)
导弹=pygame.image.load(\’element/red_pointer.png\’).convert_alpha()
x1,y1=100,600 #导弹初始发射位置
speed=800 #导弹速度
time=1/1000 #每个时间片的长度
时钟=pygame.time.Clock()
旧角度=0
而True:
对于事件pygame.event.get():
ifevent.type==pygame.QUIT:
sys.exit()
时钟.tick(300)
x,y=pygame.mouse.get_pos() #获取鼠标位置。鼠标是需要击中的目标。
distance=sqrt(pow(x1-x,2)+pow(y1-y,2)) #两点距离公式
截面=速度*时间#每个时间片内需要行驶的距离
sina=(y1-y)/距离
余弦=(x-x1)/距离
angle=atan2(y-y1,x-x1) #2条虚线段的弧度值
x1,y1=(x1+部分*科萨, y1-部分*中国)
d_angle=度(角度)#弧度转角度
screen.blit(导弹, (x1-导弹.get_width(), y1-导弹.get_height()/2))
dis_angle=d_angle-old_angle #dis_angle是你需要改变的角度
old_angle=d_angle #更新初始角度
pygame.display.update()
如果仅将导弹视为粒子,则不需要导弹旋转。当然,这是因为粒子不需要在头部或尾部旋转。加载的导弹图像很小,但不旋转似乎也没什么问题。然而,在pygame 中执行旋转并不是一件容易的事。我们先将图像替换为矩形,然后添加旋转功能,看看效果。
导弹=pygame.transform.rotate(导弹, -(d_angle))
screen.blit(导弹, (x1-导弹.get_width(), y1-导弹.get_height()/2))
图像的坐标点是左上角点,所以如果想将图像坐标固定在箭头的尖端,只需缩短图像的长度并使图像的实际打印位置x变小即可。将图像和y 宽度缩小一半。
但实际运行效果并不好。
为什么大体方向相同的情况下,图片中的箭头却始终不跟随鼠标?经过一番研究,我发现图像旋转机制有问题。让我们看看旋转后的图像是什么样子的。
旋转后的图像将位于蓝色范围内。让我们看看旋转90 度时会发生什么。
发现不仅旋转图像的面积变大,而且导弹头的位置也发生了变化。那么如何解决这个问题呢?每次旋转图像时,找到旋转图像的头部位置(图像中的绿色箭头点),并移动绿色图像的打印位置。两个头的x 和y 距离。移动以使旋转的导弹头与实际参与计算的导弹头的位置相匹配后,将如下所示:
这样,两个导弹头的点就重合了。接下来,我们将分析寻找旋转导弹头的算法。根据旋转角度的不同,每个象限的旋转角度参数都不同,所以我们分为这四种情况。
第一和第二象限
在第三象限和第四象限中,旋转仅在正负0到180度之间,因此第三象限和第四象限都是负角度。
显示图像时移动图像
screen.blit(导弹, (x1-宽度+(x1-C[0]),y1-高度/2+(y1-C[1])))
(x1-width, y1-height/2) 这实际上是上图中的(x1, y1)。
最后我添加了相关的算法代码,效果完美。
就是这样!最后附上所有算法代码。
导入pygame,系统
从数学导入*
pygame.init()
font1=pygame.font.SysFont(\’microsoftyaheimicrosoftyaheiui\’,23)
textc=font1.render(\’*\’,True,(250,0,0))
屏幕=pygame.display.set_mode((800,700),0,32)
导弹=pygame.image.load(\’element/rect1.png\’).convert_alpha()
高度=导弹.get_height()
宽度=导弹.get_width()
pygame.mouse.set_visible(0)
x1,y1=100,600 #导弹初始发射位置
speed=800 #导弹速度
time=1/1000 #每个时间片的长度
时钟=pygame.time.Clock()
A=()
B=()
C=()
而True:
对于事件pygame.event.get():
ifevent.type==pygame.QUIT:
sys.exit()
时钟.tick(300)
x,y=pygame.mouse.get_pos() #获取鼠标位置。鼠标是需要击中的目标。
distance=sqrt(pow(x1-x,2)+pow(y1-y,2)) #两点距离公式
截面=速度*时间#每个时间片内需要行驶的距离
sina=(y1-y)/距离
余弦=(x-x1)/距离
angle=atan2(y-y1,x-x1) #2 点之间线段的弧度值
fangle=度(角度)#弧度角
x1,y1=(x1+部分*科萨, y1-部分*中国)
missiled=pygame.transform.rotate(导弹,-(fangle))
如果0=-Fangle=90:
A=(宽度*cosa+x1-宽度,y1-高度/2)
B=(A[0]+身高*新浪,A[1]+身高*科萨)
如果90-方角=180:
A=(x1 – 宽度, y1 – 高度/2+高度*(-cosa))
B=(x1 – 宽度+高度*sina, y1 – 高度/2)
-90=-fangle0:
A=(x1 – 宽度+missiled.get_width(), y1 – 高度/2+missiled.get_height()-height*cosa)
B=(A[0]+高度*sina, y1 – 高度/2+missiled.get_height())
如果-180-fangle-90:
A=(x1-宽度-高度*sina, y1 – 高度/2+missiled.get_height())
B=(x1 – 宽度,A[1]+高度*cosa)
C=((A[0] + B[0])/2, (A[1] + B[1])/2)
屏幕.填充((0,0,0))
screen.blit(导弹, (x1-宽度+(x1-C[0]),y1-高度/2+(y1-C[1])))
screen.blit(textc, (x,y)) #鼠标将被替换为红色*
pygame.display.update()
上面是使用Python模拟导弹自动跟踪的代码示例。
#以上只是为了让大家了解一下怎么玩,有人用Python模拟导弹防御!相关内容来源网络仅供参考。相关信息请参见官方公告。
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/92035.html