龙马谷

 找回密码
 立即注册

QQ登录

只需一步,快速开始

龙马谷VIP会员办理客服QQ:82926983(如果临时会话没有收到回复,请先加QQ好友再发。)
1 [已完结] GG修改器新手入门与实战教程 31课 2 [已完结] GG修改器美化修改教程 6课 3 [已完结] GG修改器Lua脚本新手入门教程 12课
4 [已完结] 触动精灵脚本新手入门必学教程 22课 5 [已完结] 手游自动化脚本入门实战教程 9课 6 [已完结] C++射击游戏方框骨骼透视与自瞄教程 27课
7 [已完结] C++零基础UE4逆向开发FPS透视自瞄教程 29课 8 [已完结] C++零基础大漠模拟器手游自动化辅助教程 22课
以下是天马阁VIP教程,本站与天马阁合作,赞助VIP可以获得天马阁对应VIP会员,名额有限! 点击进入天马阁论坛
1 [已完结] x64CE与x64dbg入门基础教程 7课 2 [已完结] x64汇编语言基础教程 16课 3 [已完结] x64辅助入门基础教程 9课
4 [已完结] C++x64内存辅助实战技术教程 149课 5 [已完结] C++x64内存检测与过检测技术教程 10课 6 [已完结] C+x64二叉树分析遍历与LUA自动登陆教程 19课
7 [已完结] C++BT功能原理与x64实战教程 29课 8 [已完结] C+FPS框透视与自瞄x64实现原理及防护思路
查看: 1287|回复: 2

AI实现FPS游戏自动瞄准 yolov5 fps自瞄

[复制链接]

19

主题

1

回帖

26

积分

编程入门

Rank: 1

龙马币
58

需要了解的东西和可能会遇到的问题

1.xy坐标点与当前鼠标的xy坐标点距离计算
2.获取窗口句柄,本文使用的是根据窗口名称获取句柄
3.推理方式:本文使用的是GPU(为啥呢?速度快噻~)。
4.屏幕宽高获取和敌人坐标获取和计算哪个是最近的敌人并控制鼠标去敌人身上和头上。(为什么说是身体和头部呢,因为还有一个方式,就是只需要敌人身体坐标就可以计算得出敌人头部坐标)
5.还有鼠标按键状态获取。


正文开始吧,我们就从头开始代码解析吧。

先来一个两个xy坐标的距离计算
  1. class Point():
  2.     def __init__(self, x1, y1, x2, y2):
  3.         self.x1 = x1
  4.         self.y1 = y1
  5.         self.x2 = x2
  6.         self.y2 = y2


  7. class Line(Point):
  8.     def __init__(self, x1, y1, x2, y2):
  9.         super().__init__(x1, y1, x2, y2)

  10.     def getlen(self):
  11.         changdu = math.sqrt(math.pow((self.x1 - self.x2), 2) + math.pow((self.y1 - self.y2), 2))
  12.         return changdu
复制代码


上面这段代码的使用方式如下
  1. L1 = Line(x1, y1, x2, y2)  #传入两个xy坐标
  2. L1.getlen() #return出两个坐标点的直线距离
复制代码


接下来直接上全代码解析 各位可以把类和方法分离出去

  1. # 这里是导入依赖,需要这些库
  2. import math
  3. import sys
  4. import time

  5. import torch
  6. import win32api
  7. import win32con
  8. import win32gui
  9. from PyQt5.QtWidgets import QApplication
  10. from pynput.mouse import Controller
  11. import mouse

  12. #这里这俩class就是文章上面说的那个传入两个坐标点,计算直线距离的
  13. class Point():
  14.     def __init__(self, x1, y1, x2, y2):
  15.         self.x1 = x1
  16.         self.y1 = y1
  17.         self.x2 = x2
  18.         self.y2 = y2
  19. class Line(Point):
  20.     def __init__(self, x1, y1, x2, y2):
  21.         super().__init__(x1, y1, x2, y2)

  22.     def getlen(self):
  23.         changdu = math.sqrt(math.pow((self.x1 - self.x2), 2) + math.pow((self.y1 - self.y2), 2))
  24.         return changdu

  25. #第一步:我们获取到某FPS游戏的窗口句柄
  26. hwnd = win32gui.FindWindow(None, "穿越火线")
  27. #这个方法是获取上面句柄窗口的窗口截图,用的是PyQt截图,有速度更快更好的方式的话可以换上
  28. #截图完毕后保存在根目录的cfbg.bmp文件
  29. def screen_record():
  30.     app = QApplication(sys.argv)
  31.     screen = QApplication.primaryScreen()
  32.     img = screen.grabWindow(hwnd).toImage()
  33.     img.save("cfbg.bmp")


  34. #这里就是调用我们那yolo模型来进行推理啦,我设置的是cuda,也就是英伟达的GPU,因为cpu太慢了。
  35. #如果自己的不能使用GPU推理的话把下面这两行改改,改成cpu的就可以了。
  36. device = torch.device("cuda")
  37. model = torch.hub.load('F:/yolov5-master', 'custom', 'F:/yolov5-master/yolov5n6.pt',
  38.                        source='local', force_reload=False)  # 加载本地模型
  39. # 这里是定义屏幕宽高[其实这俩就是游戏所对应的分辨率,比如:游戏里1920*1080这里就是1920*1080]
  40. game_width = 1024
  41. game_height = 768
  42. # 这边就是开始实时进行游戏窗口推理了
  43. #无限循环 -> 截取屏幕 -> 推理模型获取到每个敌人坐标 -> 计算每个敌人中心坐标 -> 挑选距离准星最近的敌人 -> 如果左键是按下状态则控制鼠标移动到敌人的身体或者头部(本文计算方式是移动到头部)
  44. while True:
  45.     # 截取屏幕
  46.     screen_record()
  47.     # 使用模型
  48.     model = model.to(device)
  49.     img = 'cfbg.bmp'
  50.     # 开始推理
  51.     results = model(img)
  52.     # 过滤模型
  53.     xmins = results.pandas().xyxy[0]['xmin']
  54.     ymins = results.pandas().xyxy[0]['ymin']
  55.     xmaxs = results.pandas().xyxy[0]['xmax']
  56.     ymaxs = results.pandas().xyxy[0]['ymax']
  57.     class_list = results.pandas().xyxy[0]['class']
  58.     confidences = results.pandas().xyxy[0]['confidence']
  59.     newlist = []
  60.     for xmin, ymin, xmax, ymax, classitem, conf in zip(xmins, ymins, xmaxs, ymaxs, class_list, confidences):
  61.         if classitem == 0 and conf > 0.5:
  62.             newlist.append([int(xmin), int(ymin), int(xmax), int(ymax), conf])
  63.     # 循环遍历每个敌人的坐标信息传入距离计算方法获取每个敌人距离鼠标的距离
  64.     if len(newlist) > 0:
  65.         # 存放距离数据
  66.         cdList = []
  67.         xyList = []
  68.         for listItem in newlist:
  69.             # 当前遍历的人物中心坐标
  70.             xindex = int(listItem[2] - (listItem[2] - listItem[0]) / 2)
  71.             yindex = int(listItem[3] - (listItem[3] - listItem[1]) / 2)
  72.             mouseModal = Controller()
  73.             x, y = mouseModal.position
  74.             L1 = Line(x, y, xindex, yindex)
  75.             # 获取到距离并且存放在cdList集合中
  76.             cdList.append(int(L1.getlen()))
  77.             xyList.append([xindex, yindex, listItem[0], listItem[1], listItem[2], listItem[3]])
  78.         # 这里就得到了距离最近的敌人位置了
  79.         minCD = min(cdList)
  80.         # 如果敌人距离鼠标坐标小于150则自动进行瞄准,这里可以改大改小,小的话跟枪会显得自然些
  81.         if minCD < 150:
  82.             for cdItem, xyItem in zip(cdList, xyList):
  83.                 if cdItem == minCD:
  84.                     # 锁头算法:使用win32api获取左键按下状态,如果按下则开始自动跟枪
  85.                     if win32api.GetAsyncKeyState(0x01):
  86.                         # 控制鼠标移动到某个点:看不懂计算方式的话看文章下面讲解吧O(∩_∩)O
  87.                         win32api.mouse_event(win32con.MOUSEEVENTF_MOVE, int(xyItem[0] - game_width // 2),int(xyItem[1] - (game_height - (xyItem[3] - xyItem[5])) // 2), 0, 0)
  88.                     break
复制代码


好了,我们来讲解下这行代码

win32api.mouse_event(鼠标行为:这里用的是MOVE相对移动, x坐标,y坐标, 0, 0)
第一个参数,先设定鼠标的行为:使用相对移动,为什么不用绝对移动呢,因为绝对移动在游戏里是无效的
第二个参数,x轴相对移动的距离:敌人x坐标 - (屏幕宽度 / 2)
第三个参数,y轴相对移动的距离:敌人y坐标 - (屏幕高度 - (敌人最大y坐标 - 敌人最小y坐标) / 2)

第一第二个参数相对来说比较好理解,但是可能有人对于第三个y的相对移动的计算方式有点懵,我画了个图,希望可以看明白。

实例图   图比较简陋 勿喷

角度计算.jpeg

在其他fps游戏,我们只需要修改窗口名称参数和分辨率参数即可。

13

主题

8

回帖

25

积分

编程入门

Rank: 1

龙马币
36
蓝灵火焰 | 显示全部楼层
刚好可以学习一下。

10

主题

10

回帖

22

积分

编程入门

Rank: 1

龙马币
20
manarex | 显示全部楼层
讲的真好 感谢分享。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

龙马谷| C/C++辅助教程| 安卓逆向安全| 论坛导航| 免责申明|Archiver|
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表龙马谷立场!
任何人不得以任何方式翻录、盗版或出售本站视频,一经发现我们将追究其相关责任!
我们一直在努力成为最好的编程论坛!
Copyright© 2018-2021 All Right Reserved.
在线客服
快速回复 返回顶部 返回列表