Ai實現FPS遊戲自動瞄準 yolov5fps自瞄

專注的阿熊發表於2022-06-22

# 這裡是匯入依賴,需要這些庫

import math

import sys

import time

import torch

import win32api

import win32con

import win32gui

from PyQt5.QtWidgets import QApplication

from pynput.mouse import Controller

import mouse

# 這裡這倆 class 就是文章上面說的那個傳入兩個座標點,計算直線距離的

class Point():

     def __init__(self, x1, y1, x2, y2):

         self.x1 = x1

         self.y1 = y1

         self.x2 = x2

         self.y2 = y2

class Line(Point):

     def __init__(self, x1, y1, x2, y2):

         super().__init__(x1, y1, x2, y2)

     def getlen(self):

         changdu = math.sqrt(math.pow((self.x1 - self.x2), 2) + math.pow((self.y1 - self.y2), 2))

         return changdu

# 第一步:我們獲取到某 FPS 遊戲的視窗控制程式碼

hwnd = win32gui.FindWindow(None, " 穿越火線 ")

# 這個方法是獲取上面控制程式碼視窗的視窗截圖,用的是 PyQt 截圖,有速度更快更好的方式的話可以換上

# 截圖完畢後儲存在根目錄的 cfbg.bmp 檔案

def screen_record():

     app = QApplication(sys.argv)

     screen = QApplication.primaryScreen()

     img = screen.grabWindow(hwnd).toImage()

     img.save("cfbg.bmp")

# 這裡就是呼叫我們那 yolo 模型來進行推理啦,我設定的是 cuda ,也就是英偉達的 GPU ,因為 cpu 太慢了。

# 如果自己的不能使用 GPU 推理的話把下面這兩行改改,改成 cpu 的就可以了。

device = torch.device("cuda")

model = torch.hub.load('F:/yolov5-master', 'custom', 'F:/yolov5-master/yolov5n6.pt',

                        source='local', force_reload=False)  # 載入本地模型

# 這裡是定義螢幕寬高 [ 其實這倆就是遊戲所對應的解析度,比如:遊戲裡 1920*1080 這裡就是 1920*1080]

game_width = 1024

game_height = 768

# 這邊就是開始實時進行遊戲視窗推理了

# 無限迴圈 ->外匯跟單gendan5.com  擷取螢幕 -> 推理模型獲取到每個敵人座標 -> 計算每個敵人中心座標 -> 挑選距離準星最近的敵人 -> 如果左鍵是按下狀態則控制滑鼠移動到敵人的身體或者頭部 ( 本文計算方式是移動到頭部 )

while True:

     # 擷取螢幕

     screen_record()

     # 使用模型

     model = model.to(device)

     img = 'cfbg.bmp'

     # 開始推理

     results = model(img)

     # 過濾模型

     xmins = results.pandas().xyxy[0]['xmin']

     ymins = results.pandas().xyxy[0]['ymin']

     xmaxs = results.pandas().xyxy[0]['xmax']

     ymaxs = results.pandas().xyxy[0]['ymax']

     class_list = results.pandas().xyxy[0]['class']

     confidences = results.pandas().xyxy[0]['confidence']

     newlist = []

     for xmin, ymin, xmax, ymax, classitem, conf in zip(xmins, ymins, xmaxs, ymaxs, class_list, confidences):

         if classitem == 0 and conf > 0.5:

             newlist.append([int(xmin), int(ymin), int(xmax), int(ymax), conf])

     # 迴圈遍歷每個敵人的座標資訊傳入距離計算方法獲取每個敵人距離滑鼠的距離

     if len(newlist) > 0:

         # 存放距離資料

         cdList = []

         xyList = []

         for listItem in newlist:

             # 當前遍歷的人物中心座標

             xindex = int(listItem[2] - (listItem[2] - listItem[0]) / 2)

             yindex = int(listItem[3] - (listItem[3] - listItem[1]) / 2)

             mouseModal = Controller()

             x, y = mouseModal.position

             L1 = Line(x, y, xindex, yindex)

             # 獲取到距離並且存放在 cdList 集合中

             cdList.append(int(L1.getlen()))

             xyList.append([xindex, yindex, listItem[0], listItem[1], listItem[2], listItem[3]])

         # 這裡就得到了距離最近的敵人位置了

         minCD = min(cdList)

         # 如果敵人距離滑鼠座標小於 150 則自動進行瞄準,這裡可以改大改小,小的話跟槍會顯得自然些

         if minCD < 150:

             for cdItem, xyItem in zip(cdList, xyList):

                 if cdItem == minCD:

                     # 鎖頭演算法:使用 win32api 獲取左鍵按下狀態,如果按下則開始自動跟槍

                     if win32api.GetAsyncKeyState(0x01):

                         # 控制滑鼠移動到某個點:看不懂計算方式的話看文章下面講解吧 O( _ )O

                         win32api.mouse_event(win32con.MOUSEEVENTF_MOVE, int(xyItem[0] - game_width // 2),int(xyItem[1] - (game_height - (xyItem[3] - xyItem[5])) // 2), 0, 0)

                     break


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69946337/viewspace-2902271/,如需轉載,請註明出處,否則將追究法律責任。

相關文章