一,前言

自动追踪算法,在我们制作射击类游戏时经常会用到。这个听起来很高大上的东西,其实并不是军事学的专利,从数学上来说就是解微分方程,

这个没有点数学基础是很难算出来的。但是我们有了计算机就不一样了,依靠计算机极快速的运算速度,我们利用微分的思想,加上一点简单的三角学知识,就可以实现它。

好,话不多说,我们来看看它的算法原理,看图:

由于待会要用pygame演示,它的坐标系是y轴向下,所以这里我们也用y向下的坐标系。

算法总的思想就是根据上图,把时间t分割成足够小的片段(比如1/1000,这个时间片越小越精确),每一个片段分别构造如上三角形,计算出导弹下一个时间片走的方向(即∠a)和走的路程(即vt=|AC|),这时候目标再在第二个时间片移动了位置,这时刚才计算的C点又变成了第二个时间片的初始点,这时再在第二个时间片上在C点和新的目标点构造三角形计算新的vt,然后进入第三个时间片,如此反复即可。

假定导弹和目标的初始状态下坐标分别是(x1,y1),(x,y),构造出直角三角形ABE,这个三角形用来求∠a的正弦和余弦值,因为vt是自己设置的,我们需要计算A到C点x和y坐标分别移动了多少,移动的值就是AD和CD的长度,这两个分别用vt乘cos(a)和sin(a)即可。计算sin(a)和cos(a),正弦对比斜,余弦邻比斜,斜边可以利用两点距离公式计算出,即:

于是

AC的长度就是导弹的速度乘以时间即 |AC|=vt,然后即可计算出AD和CD的长度,于是这一个时间片过去后,导弹应该出现在新的位置C点,他的坐标就是老的点A的x增加AD和y减去CD。

于是,新的C点坐标就是:

只要一直反复循环执行这个操作即可,好吧,为了更形象,把第一个时间片和第二个时间片放在一起看看:

第一个是时间片构造出的三角形是ABE,经过一个时间片后,目标从B点走到了D点,导弹此时在C点,于是构造新的三角形CDF,重复刚才的计算过程即可,图中的角∠b就是导弹需要旋转的角度,现实中只需要每个时间片修正导弹的方向就可以了,具体怎么让导弹改变方向,这就不是我们需要研究的问题了

好,由于最近在用Python的pygame库制作小游戏玩,接下来我们就用pygame来演示一下这个效果,效果如下图:

很简单的代码如下:

import pygame,sys
from math import *
pygame.init()
screen=pygame.display.set_mode((800,700),0,32)
missile=pygame.image.load('element/red_pointer.png').convert_alpha()
x1,y1=100,600           #导弹的初始发射位置
velocity=800            #导弹速度
time=1/1000             #每个时间片的长度
clock=pygame.time.Clock()
old_angle=0
while True:for event in pygame.event.get():if event.type==pygame.QUIT:sys.exit()clock.tick(300)x,y=pygame.mouse.get_pos()          #获取鼠标位置,鼠标就是需要打击的目标distance=sqrt(pow(x1-x,2)+pow(y1-y,2))      #两点距离公式section=velocity*time               #每个时间片需要移动的距离sina=(y1-y)/distancecosa=(x-x1)/distanceangle=atan2(y-y1,x-x1)              #两点线段的弧度值x1,y1=(x1+section*cosa,y1-section*sina)d_angle = degrees(angle)        #弧度转角度screen.blit(missile, (x1-missile.get_width(), y1-missile.get_height()/2))dis_angle=d_angle-old_angle          #dis_angle就是到下一个位置需要改变的角度old_angle=d_angle                    #更新初始角度pygame.display.update()

如果仅把导弹考虑为一个质点的话,那么以上算法就已经足矣,我没有做导弹的旋转,因为一个质点也不分头尾不需要旋转,当然这前提得是你加载的导弹图片很小的时候不旋转看起来也没什么问题。但是在pygame里面做旋转并不是一件容易的事情,我们先把图片替换成一张矩形的,再加入旋转函数看看效果如何

missiled = pygame.transform.rotate(missile, -(d_angle))screen.blit(missiled, (x1-missile.get_width(), y1-missile.get_height()/2)) 

因为图片的坐标点是它的左上角的点,所以如果我们想让图片的坐标固定在箭头尖点,那么把图片实际打印位置x减少图片长度,y减少一半宽度就行。但是实际运行效果并不好

大致方向相同,但是图片箭头的尖点并没有一直跟随鼠标,这是为什么呢。经过一番研究,我发现原来是这个图旋转的机制问题,我们看看旋转后的图片变成什么样了:

旋转后的图片变成了蓝色的那个范围,根据旋转角度的不同,所变成的图片大小也不一样,我们看旋转90的情况

我们发现,旋转后的图片不仅面积变大了,导弹头的位置也变了。那应该怎么解决这个问题呢?思路是,每一次旋转图片以后,求出旋转图的头位置(图中的绿色箭头点),然后把绿图的打印位置移动一下,下,x,y分别移动两个头的距离,就可以让旋转后的导弹头对准实际我们参与运算的那个导弹头的位置,移动后应该是这样的:

这样,两个导弹头的点就一致了。接下来我们分析求旋转后的导弹头的算法。根据旋转角度的不同,旋转角在不同象限参数不一样,所以我们分为这四种情况1,2象限

3,4象限,它的旋转只有正负0—180,所以3,4象限就是负角

显示图片的时候我们将他移动

 

screen.blit(missiled, (x1-width+(x1-C[0]),y1-height/2+(y1-C[1])))

这里的 (x1-width, y1-height/2) 其实才是上图中的 (x1, y1)所以最后我们加入相关算法代码,效果就比较完美了

大功告成,最后附上全部的算法代码

import pygame,sys
from math import *
pygame.init()
font1=pygame.font.SysFont('microsoftyaheimicrosoftyaheiui',23)
textc=font1.render('*',True,(250,0,0))
screen=pygame.display.set_mode((800,700),0,32)
missile=pygame.image.load('element/rect1.png').convert_alpha()
height=missile.get_height()
width=missile.get_width()
pygame.mouse.set_visible(0)
x1,y1=100,600           #导弹的初始发射位置
velocity=800            #导弹速度
time=1/1000             #每个时间片的长度
clock=pygame.time.Clock()
A=()
B=()
C=()
while True:for event in pygame.event.get():if event.type==pygame.QUIT:sys.exit()clock.tick(300)x,y=pygame.mouse.get_pos()          #获取鼠标位置,鼠标就是需要打击的目标distance=sqrt(pow(x1-x,2)+pow(y1-y,2))      #两点距离公式section=velocity*time               #每个时间片需要移动的距离sina=(y1-y)/distancecosa=(x-x1)/distanceangle=atan2(y-y1,x-x1)              #两点间线段的弧度值fangle=degrees(angle)               #弧度转角度x1,y1=(x1+section*cosa,y1-section*sina)missiled=pygame.transform.rotate(missile,-(fangle))if 0<=-fangle<=90:A=(width*cosa+x1-width,y1-height/2)B=(A[0]+height*sina,A[1]+height*cosa)if 90<-fangle<=180:A = (x1 - width, y1 - height/2+height*(-cosa))B = (x1 - width+height*sina, y1 - height/2)if -90<=-fangle<0:A = (x1 - width+missiled.get_width(), y1 - height/2+missiled.get_height()-height*cosa)B = (A[0]+height*sina, y1 - height/2+missiled.get_height())if -180<-fangle<-90:A = (x1-width-height*sina, y1 - height/2+missiled.get_height())B = (x1 - width,A[1]+height*cosa )C = ((A[0] + B[0]) / 2, (A[1] + B[1]) / 2)screen.fill((0,0,0))screen.blit(missiled, (x1-width+(x1-C[0]),y1-height/2+(y1-C[1])))screen.blit(textc, (x,y)) #鼠标用一个红色*代替pygame.display.update()

以上便是用Python模拟导弹自动追踪的代码实例。

如果文章对你有帮助,欢迎转发/点赞/收藏~

没有一点高数算法功底的话 估计回有点懵,多看几次就懂了,所以说游戏外挂也是一门技术活,哈哈哈!

近期有很多朋友通过私信咨询有关Python学习问题。为便于交流,点击蓝色自己加入讨论解答资源基地 完整代码点击获取哦

Python实现吃鸡游戏子弹and导弹自动追踪!原来是这样的一个原理啊!相关推荐

  1. 用Python解析吃鸡游戏的真相

    近期在Kaggle里发现一个有趣的项目.他提供了一个端游吃鸡的数据包,里面有近百局吃鸡游戏中各种游戏内部的量化数据,这绝壁是个好东西,能挖掘出各种有趣的结论.所以今天就用吃鸡比赛的真实数据来看看如何提 ...

  2. 吃鸡是python写的吗_吃鸡游戏也是用Python写的?学了Python,120个月年终奖向你招手~...

    原标题:吃鸡游戏也是用Python写的?学了Python,120个月年终奖向你招手~ 吃鸡游戏火爆全球,已经把腾讯的<王者荣耀>都比下去了,有传言,腾讯给"王者荣耀"开 ...

  3. 教你用Python解锁“吃鸡”的正确姿势!(附240行代码)

    来源:经济人学数据分析 本文约2554字,建议阅读6分钟. 本文用Python分析吃鸡比赛的真实数据,解答至关重要的9个问题,助你提高吃鸡概率. 大吉大利,今晚吃鸡~ 今天跟朋友玩了几把吃鸡,经历了各 ...

  4. mac版免费吃鸡游戏(荒野行动)

    最近吃鸡游戏非常的火爆,现为大家推出一款Mac腾讯吃鸡游戏"荒野行动 for Mac",是由网易游戏研发的一款射击求生类游戏,该游戏讲述了远洋岛事件爆发之后,小岛遭到极端分子洗劫的 ...

  5. Unity3DPhoton制作吃鸡游戏

    Unity3D&Photon制作吃鸡游戏 https://study.163.com/course/courseMain.htm?share=1&shareId=8348227& ...

  6. 吃鸡游戏(18.11.24)

    吃鸡游戏 Description xxx 吃鸡成瘾.为此他决定逃课吃鸡!但是学校有规定,旷课到一定次数,是不给予期末考的资格的.因此 xxx 决定每门课最多逃两次.现在告诉你,一个学期有 nnn 节课 ...

  7. 教你用Python解锁“吃鸡”的正确姿势!

    本文用Python分析吃鸡比赛的真实数据,解答至关重要的9个问题,助你提高吃鸡概率. 大吉大利,今晚吃鸡~ 今天跟朋友玩了几把吃鸡,经历了各种死法,还被嘲笑说论女生吃鸡的100种死法,比如被拳头抡死. ...

  8. 计算机内存不足吃鸡怎么办,Win10玩吃鸡游戏提示虚拟内存不足怎么办?

    Win10玩吃鸡游戏提示"虚拟内存不足"怎么办? 最近吃鸡游戏非常火,大家都想大吉大利晚上吃鸡!因为吃鸡游戏对电脑配置的要求非常高,所以很多用户在玩吃鸡手游时会遇到各种问题,最常见 ...

  9. 达威尔CHERRY樱桃轴 铝合金有线背光电竞吃鸡游戏机械键盘

    作为一名电脑办公的打工仔,如果你有四五年以上的工作经验,可以毫不夸张地说,你至少用过三只以上的键盘了吧?这是最少的了,有的朋友用过的键盘都有十几把了,用过的键盘牌子也有不少了.我打工几年,就用过好几个 ...

最新文章

  1. Relay外部库使用
  2. hdu1715(Java)大数相加
  3. 【编程】为什么不能直接对链表头head进行操作?
  4. ES6一些新特性记录
  5. 阿里云分析型数据库AnalyticDB:使用Logstash插件进行高效数据写入
  6. Booting Android: bootloaders, fastboot and boot images
  7. MDaemon的邮件撤回功能详细介绍
  8. 19.为什么要用异步框架,它解决什么问题?
  9. 《Effective Debugging:软件和系统调试的66个有效方法》——导读
  10. 一个好的热修复技术,将为你的 App助力百倍
  11. 根据视频链接并下载视频(mp4格式)
  12. 3个国内最大的黑客学习网站
  13. 由于您的系统没有安装html help,教你解决Chrome浏览器未安装flash控件方法
  14. Ubuntu18.04设置开机启动脚本__NVIDIA Jetson xavier NX设置开机启动脚本
  15. 第四章:迭代器与生成器
  16. 程序员的英文代号_构建一个代号为1的聊天应用程序4
  17. Win11里面【应用或关闭Windows功能】在哪
  18. OKR工作法的简单总结
  19. 用java怎么写三角形图案_Java 打印三角形图案
  20. 2022年中级网络工程师备考(非网络知识部分)

热门文章

  1. [游戏]_纪念一下dnf,安心准备考研
  2. 微信接收消息还会有延迟?估计是以下原因造成的,很常见但能避免
  3. 自动化办公之乘法口诀打印
  4. lol 服务器维护2019年2月26日,LOL3月26日维护到几点 2019lol3月26日为什么还在维护中...
  5. ARIMA模型进行销售数据预测
  6. Bentley SYNCHRO系统+智慧工地在变电站工程中的应用
  7. 基于MDKA5D31-EK_T70开发板的QT示例-demo12:pcf8562演示
  8. 通过执行nbtstat命令获取MAC地址
  9. 转---找女朋友的标准
  10. 如何将FAT32格式转换为NTFS格式(一)