使用Python和YOLOv8开发视频游戏的目标检测和鼠标重新定位

视频游戏已经走过了漫长的发展历程,从最初的谦卑起步到现在,先进的图形和游戏机制已经成为常态。现代游戏的一个显著发展方向是将人工智能和计算机视觉技术整合到游戏体验中。在本文中,我们将探讨如何使用Python和YOLOv8创建一个系统,结合目标检测和鼠标重新定位,以提升视频游戏的体验。

1 窗口捕获:用于捕获屏幕的Python库

首先,您需要捕获游戏窗口。Python提供了一些用于此任务的库,例如pyautogui、Pillow或mss。这些库使您能够实时捕获游戏的屏幕截图,从而使您的Python脚本能够分析游戏环境。

import mss
sct = mss.mss()
img = np.array(self.sct.grab({"top": 0, "left": 0, "width": 800, "height": 800}))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

2 区域选择:关注关键区域

对于大多数视频游戏,不需要持续分析整个屏幕。相反,关注靠近玩家鼠标光标或瞄准镜的区域。这个小区域是所有动作发生的地方,通过这样做,您可以节省计算资源。

@dataclass
class Monitor:
    top:int =  0
    left:int = 0
    width:int = 1920
    height:int = 1080


    @property
    def sizes(self):
       return {"top": self.top, "left": self.left, "width": self.width, "height": self.height}






#Inside your main loop. In this case I decided to inspect a region of 320x320 centered in the center of the screen
window_title = "Fortnite"
screenShotHeight = 320
screenShotWidth = 320
monitor = Monitor()
selected_window = gw.getWindowsWithTitle(window_title)[0]
window_shape = (selected_window.getClientFrame())
window_w = window_shape.right - window_shape.left
window_h = window_shape.bottom - window_shape.top


monitor.top = int((window_shape.bottom + window_shape.top) / 2 - screenShotHeight/2)
monitor.left = int((window_shape.right + window_shape.left) / 2 - screenShotWidth/2)


monitor.width = screenShotWidth
monitor.height = screenShotHeight

3 目标检测:识别相关对象

这个系统的核心是目标检测。YOLOv8(You Only Look Once)是一种用于实时目标检测的强大深度学习模型。通过使用预训练的YOLOv8模型或训练自己的模型,您可以检测到重要的游戏元素,如敌人或目标。

3.1 丢弃自身检测

在第三人称游戏中,玩家角色常常出现在画面中。为了防止自身检测,您可以配置一个手动区域,将玩家角色的模型排除在外。

#We manually define where the self player is and set that area to zeros
inity = 200
endy = 320
initx = 0
endx = 180
img = self.grab_screen(monitor)  # Grab screen image        
img[inity:endy,initx:endx] = 0
cv_image = self.aim(img)

3.2 目标选择:选择正确的对象

检测到对象后,您需要选择最相关的目标。在大多数第一人称射击游戏中,您希望瞄准敌人。为了实现这一点,考虑以下标准:

  • 距离:计算每个检测到的对象与瞄准镜或鼠标光标之间的距离。

  • 角度(可选):确定视线和每个对象之间的角度。

  • 优先级:选择距离最短且角度最有利的对象。

def findTarget(self,frame):
        targets = []
        results = self.model.predict(frame,device=self.device,conf=self.config.confidence,verbose=False,classes=0,imgsz=int(self.config.screenShotWidth/2))[0]
        boxes = results.cpu().numpy().boxes.data
        
        for output in boxes:
            bbox_tl_x = int(output[0])
            bbox_tl_y = int(output[1])
            bbox_br_x = int(output[2])
            bbox_br_y = int(output[3])
            mid_x = (bbox_tl_x + bbox_br_x ) /2
            mid_y = (bbox_tl_y + bbox_br_y ) /2
            targets.append([mid_x,mid_y,bbox_br_x-bbox_tl_x,bbox_br_y-bbox_tl_y,output[4]])
            if self.config.visuals:
                cv2.rectangle(frame, (bbox_tl_x, bbox_tl_y),(bbox_br_x, bbox_br_y), color=self.color, thickness=self.line_thickness) 
                cv2.circle(frame,(int(mid_x),int(mid_y)), 3,self.color, -1)
        targets = pd.DataFrame(
                targets, columns=['current_mid_x', 'current_mid_y', 'width', "height", "confidence"])
        # If there are people in the center bounding box
        if len(targets) > 0:
            last_mid_coord = None
            # Get the last persons mid coordinate if it exists
            if last_mid_coord:
                targets['last_mid_x'] = last_mid_coord[0]
                targets['last_mid_y'] = last_mid_coord[1]
                # Take distance between current person mid coordinate and gun sight
                targets['dist'] = np.linalg.norm(
                    targets[['current_mid_x', 'current_mid_y']].values - [0,self.config.screenShotHeight/2], axis=1)
                targets.sort_values(by="dist", ascending=False)
        return targets

4 鼠标移动:平滑而精准

一旦选择了目标,就是重新定位鼠标光标的时候了。像pyautogui这样的Python库可以帮助您平滑而精准地移动鼠标。您可以将最终鼠标位置设置为检测到的对象的中心,还可以选择一个Y轴偏移以便聚焦在敌人的头部或特定的命中区域上。

def shoot(self,target,only_focus=False):
        box_height = target.height
    #Optional: point to head
        if self.config.headshot_mode:
            headshot_offset = box_height * 0.1
        else:
            headshot_offset = 0
        deltax = int(target.current_mid_x - self.config.screenShotWidth/2 + self.shift) * self.config.aaMovementAmp
        deltay = int(target.current_mid_y - self.config.screenShotHeight/2 - headshot_offset) * self.config.aaMovementAmp


        logger.info(f"Shooting to {target.current_mid_x},{target.current_mid_y} Delta {deltax},{deltay}. Current mouse position: {pyautogui.position()}")
        
        
        win32api.mouse_event(win32con.MOUSEEVENTF_MOVE,int(deltax), int(deltay),0,0)
        if not only_focus:
            win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
            time.sleep(0.07)
            win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)

5 结论

使用Python和YOLOv8开发视频游戏的目标检测和鼠标重新定位提供了一种主要用于研究目的的新颖方法。值得注意的是,将这项技术应用于增强游戏体验可能被视为一种作弊行为,可能影响游戏环境的公平性和完整性。虽然这个系统创新,但不鼓励其用于常规游戏。在使用前,请务必考虑伦理影响,并遵守游戏社区的规定和指南。与其用于获得游戏优势,我鼓励您将其用于研究和实验,以更好地了解其能力以及在人工智能和计算机视觉领域的潜在应用。

3264af9b4ff52b25bee833591c191860.png

·  END  ·

HAPPY LIFE

a97e606822cb78174c2e2b12f3d6c8f3.png

本文仅供学习交流使用,如有侵权请联系作者删除

最近更新

  1. TCP协议是安全的吗?

    2024-01-10 15:20:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-10 15:20:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-10 15:20:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-10 15:20:01       20 阅读

热门阅读

  1. Oracle19c文档 tnsnames.ora (三)

    2024-01-10 15:20:01       36 阅读
  2. 5个免费、跨平台的SQLite数据库可视化工具

    2024-01-10 15:20:01       39 阅读
  3. 安全防御之可信计算技术

    2024-01-10 15:20:01       40 阅读
  4. python爬虫实战(6)--获取某度热榜

    2024-01-10 15:20:01       36 阅读