Python实现-透视方框绘制

前言

对于FPS游戏的外挂,最常见的就是透视,而透视必然要用到方框绘制功能,C++和易语言在这方面的教程比比皆是,但是Python搜出来的几乎全是用PyGame或小海龟在自身创建的窗口上绘制方框,然后你就会想:"哥们!!!我是要在其他程序上绘制方框啊!!",当然实际上你以为的这种绘制也并非是真正的在FPS窗口上绘制,请看如下原理。

原理

在FPS游戏上的方框绘制并非真正是在程序窗口上绘制,实际上是找到敌人在游戏中的坐标x,y,z,找到自己在游戏中的坐标x,y,z,结合通过分析象限角度和FOV视角计算出人物在我方屏幕上的坐标,然后通过程序在屏幕上根据得出的坐标绘制方框。

目的

本篇文章不会讲解3D游戏中的绘制,只讲解如何通过Python在屏幕上绘制方框,因为网上对Python在这方面的教程实在太少了,几乎无,看完此文章,你也可以学到一些WindowsAPI函数,这里我们以CE自带教程的第二关为例绘制方框。

正文

分析

如下图,我们要通过Python在健康值上绘制方框,并能使方框跟随目标移动,FPS中是通过一系列计算获取到坐标绘制,这里我们为演示绘制,简单的通过窗口子句柄获取到其在屏幕上的坐标,绘制原理是一样的,只是坐标寻找不同。

所需库引入

python 复制代码
import ctypes
import win32gui, win32api
from pywinauto.win32functions import *
from pywinauto.win32structures import RECT

第一步:获取健康值的窗口句柄

健康值也是一个窗口,是步骤2这个大窗口的子窗口,他也有自己的句柄。

方式一:

直接通过Spy++获取到健康值的句柄,然后定义变量保存即可。注意!!窗口每次打开其窗口句柄是会变化的,请勿直接复制粘贴。

python 复制代码
healthHandle=0x00070406

方式二:

通过父窗口的标题和类名找到健康值这个子窗口的句柄。这样就可以避免第一种方式带来的问题。

语句解释:先通过Spy++查询到步骤2的窗口标题是"步骤 2"(注意有1个空格),类名是"Window"(可以填None),然后获取到父窗口句柄。再定义一个存放子窗口句柄的列表,然后通过父窗口句柄将其所有子窗口句柄作为参数追加到列表中,

python 复制代码
WindowHandle=win32gui.FindWindow("Window","步骤 2")
childrenWindowHandle=[]
win32gui.EnumChildWindows(WindowHandle,lambda hwnd,param: param.append(hwnd),childrenWindowHandle)

然后,定义一个变量用于存放健康值的句柄,从众多的字句柄中同样根据健康值窗口标题和类名将其取出。

python 复制代码
healthHandle=None
for obj in childrenWindowHandle:
    if win32gui.GetWindowText(obj)=="" and win32gui.GetClassName(obj)=="Window":
        healthHandle=int(obj)

第二步:绘制所需相关对象准备

既然是绘制,那么绘制就需要画刷(Brush),还需要一个用于绘制的板子,这里我们绘制的板子就是整个屏幕,屏幕我们称之为设备上下文(DeviceContext),简称DC,绘制在哪呢,当然是健康值这个句柄的边界(Rect) ,定义对象如下:

语句解释:

第一句通过win32gui获取到设备上下文,传入0表示整个屏幕

第二步定义了一个边界结构体Rect,用于存放后续获取到的健康值句柄边界

第三步我们定义了一个画刷,红色的

有了如下工具,就可以开始循环绘制以实现方框跟随目标的移动

python 复制代码
dc = win32gui.GetDC(0)
rect=RECT()
brush=win32gui.CreateSolidBrush(win32api.RGB(255, 0, 0))

第三步:循环绘制

语句解释:

GetWindowRect表示获取一个句柄在相对于整个屏幕的坐标信息,此句一执行,rect对象将会存放句柄相对于整个屏幕的坐标信息,其中left表示健康值句柄左上角点相对于屏幕左边像素点大小,top表示左上角点相对于整个屏幕顶部的像素点大小,right表示右下角点相对于整个屏幕左边的像素点大小,bottom表示右下角点相对于整个屏幕顶部的像素点大小。

FrameRect表示在整个屏幕用画刷在传入的位置进行绘制,至此绘制功能实现。

python 复制代码
while True:
    GetWindowRect(healthHandle, rect)
    l=rect.left
    t=rect.top
    r=rect.right
    b=rect.bottom
    win32gui.FrameRect(dc,(l, t, r, b),brush)

结果:

拖动窗口可以看见,所绘制的方框跟随着目标移动。(这里由于GIF录制,表现出闪烁严重)

社群分享:

加入Q群:307531422 ,一起学习不一样的技术

相关推荐
喵叔哟7 分钟前
重构代码中引入外部方法和引入本地扩展的区别
java·开发语言·重构
尘浮生13 分钟前
Java项目实战II基于微信小程序的电影院买票选座系统(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven·intellij-idea
hopetomorrow26 分钟前
学习路之PHP--使用GROUP BY 发生错误 SELECT list is not in GROUP BY clause .......... 解决
开发语言·学习·php
小牛itbull36 分钟前
ReactPress vs VuePress vs WordPress
开发语言·javascript·reactpress
请叫我欧皇i1 小时前
html本地离线引入vant和vue2(详细步骤)
开发语言·前端·javascript
nuclear20111 小时前
使用Python 在Excel中创建和取消数据分组 - 详解
python·excel数据分组·创建excel分组·excel分类汇总·excel嵌套分组·excel大纲级别·取消excel分组
闲暇部落1 小时前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
GIS瞧葩菜1 小时前
局部修改3dtiles子模型的位置。
开发语言·javascript·ecmascript
chnming19871 小时前
STL关联式容器之set
开发语言·c++
Lucky小小吴1 小时前
有关django、python版本、sqlite3版本冲突问题
python·django·sqlite