tão legal! A versão Python dos campos de batalha do PlayerUnknown!

618e59f67baa2eade6fe9f60ec4bf200.png

(Para sempre grátis, escaneie o código para participar)

Por LookOutTheBush

https://juejin.cn/post/7232253274056785957

Somente para aprendizado e intercâmbio, sem fins lucrativos

I. Visão geral

1.1 Efeito

8d8696b267a0b24fb6adbe3ddaaa3833.gif

Em geral, esse método é realizado por meio de reconhecimento de imagem, sem interferir no jogo, sem ler a memória e sem ser detectado com segurança.

1.2 Pré-requisito de conhecimento

  1. Há uma variedade de armas de fogo diferentes no jogo. Diferentes armas de fogo têm diferentes recuos e diferentes taxas de disparo. A mesma arma de fogo, após a instalação de vários acessórios, o recuo também mudará.

  2. O movimento ascendente do eixo y da arma de fogo é fixo e o eixo x é aleatório, então nosso programa move apenas o eixo y do mouse. Operação manual no jogo do eixo x.

1.3 Breve descrição do princípio de realização

  1. Monitore o teclado e o mouse através do módulo pynput em python.

Ouça o botão esquerdo do mouse ser pressionado e comece a mover o mouse neste momento. Levante o botão esquerdo para parar de se mover. Monitore as teclas do teclado, como a tecla tab, abra a mochila neste momento, faça uma captura de tela e comece a identificar a coluna do equipamento.

  1. Use o módulo pyautogui do python para fazer capturas de tela e você pode capturar a tela em um local especificado.

  2. As imagens interceptadas são processadas através do módulo opencv do python.

  3. Use o algoritmo SSIM para comparar a semelhança das imagens e obtenha as armas e acessórios na barra de equipamentos.

  4. Manipule o movimento do mouse por meio do pydirectinput do python.

Dois, explicação detalhada

teclado de monitor pynput 2.1

import pynput.keyboard as keyboard

# 监听键盘
def listen_keybord():
    listener = keyboard.Listener(on_press=onPressed, on_release=onRelease)
    listener.start()

O ouvinte do pynput é um evento assíncrono, mas será bloqueado, portanto, se o evento de processamento do evento for muito longo, ele deverá ser processado de forma assíncrona.

2.2 Ouvindo eventos

A classe c_equipment foi criada para encapsular as informações da arma. O foco está no monitoramento da tecla tab, utilizando assíncrono para detectar informações do equipamento.

def onRelease(key):
    try:
        if '1' == key.char:
            c_equipment.switch = 1 #主武器1
        elif '2' == key.char:
            c_equipment.switch = 2 #主武器2
        elif '3' == key.char:
            c_equipment.switch = 3 #手枪 switch=3的时候不压枪
        elif '4' == key.char:
            c_equipment.switch = 3 #刀具
        elif '5' == key.char:
            c_equipment.switch = 3 #手雷
    except AttributeError:
        if 'tab' == key.name:      #tab键异步操作检测
            asyncHandle()
        elif 'num_lock' == key.name:  #小键盘锁用来控制程序开关
            changeOpen()
        elif 'shift' == key.name:   
            c_contants.hold = False

2.3 captura de tela do pyautogui

Para detectar equipamentos, você deve primeiro fazer uma captura de tela ao abrir a barra de equipamentos.

pyautogui.screenshot(region=[x, y, w, h])

x,y representam as coordenadas respectivamente, w,h representam a largura e a altura. Após a interceptação, para comparar as imagens convenientemente, a imagem precisa ser binarizada e salva localmente.

O código completo é o seguinte:

import pyautogui

def adaptive_binarization(img):
    #自适应二值化
    maxval = 255
    blockSize = 3
    C = 5
    img2 = cv2.adaptiveThreshold(img, maxval, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, blockSize, C)
    return img2

# 屏幕截图
def shotCut(x, y, w, h):
    im = pyautogui.screenshot(region=[x, y, w, h])
    screen = cv2.cvtColor(numpy.asarray(im), cv2.COLOR_BGR2GRAY)
    temp = adaptive_binarization(screen)
    return temp
    
def saveScreen():
    screen1 = shotCut(1780, 125, 614, 570)
    cv2.imwrite("./resource/shotcut/screen.bmp", screen1)
4021561a8f8f6df495b5c78c3da420a7.jpeg

2.4 Preparação de materiais

Depois que a captura de tela é processada como acima, antes do reconhecimento do equipamento, precisamos preparar muitas imagens de material para comparação. Por exemplo: nome da arma, coronha, empunhadura, focinho

b84d68fda4de582cf1f20264a301aeb6.jpeg

Nome da arma:

ec959c75606c3ef007e049f4786735fe.jpeg

estoque de armas

7386fea7067a4551d1c9919465687419.jpeg

2.5 Cortar Imagem

Para facilitar a comparação de imagens, precisamos recortar a imagem capturada da coluna do equipamento em uma imagem do mesmo tamanho do material.

Por exemplo, queremos verificar o nome da arma um:

#读取之前的截屏
screen = cv2.imread("./resource/shotcut/screen.bmp", 0)
#裁剪出武器1名字
screenWepon1 = screen[0:40, 45:125]
#拿裁剪的图片和武器素材的目录作为入参,进行对比
w1Name = compareAndGetName(screenWepon1, "./resource/guns/")

2.6 Imagens de comparação

#对比图片获取名字
def compareAndGetName(screenImg, dir):
    #获取目录下所有文件
    content = os.listdir(dir)
    name = 'none'
    max = 0
    #遍历文件
    for fileName in content:
        #使用opencv读取文件
        curWepone = cv2.imread(dir + fileName, 0)
        #使用SSIM算法拿到图片相似度
        res = calculate_ssim(numpy.asarray(screenImg), numpy.asarray(curWepone))
        #获取相似度最大的
        if max < res and res > 0.5:
            max = res
            name = str(fileName)[:-4]
    return name

Algoritmo SSIM:

def calculate_ssim(img1, img2):
    if not img1.shape == img2.shape:
        raise ValueError('Input images must have the same dimensions.')
    if img1.ndim == 2:
        return ssim(img1, img2)
    elif img1.ndim == 3:
        if img1.shape[2] == 3:
            ssims = []
            for i in range(3):
                ssims.append(ssim(img1, img2))
            return numpy.array(ssims).mean()
        elif img1.shape[2] == 1:
            return ssim(numpy.squeeze(img1), numpy.squeeze(img2))
    else:
        raise ValueError('Wrong input image dimensions.')

Neste ponto, podemos obter o nome da arma na posição 1 da barra de equipamento.

2.7 Operando o mouse

Depois de saber o nome da arma, da mesma forma, podemos obter os acessórios do equipamento. Em seguida, ouça os pressionamentos do botão esquerdo do mouse e comece a mover o mouse para baixo.

Vamos pegar a arma m762 como exemplo:

Taxa de tiro: 86, cada intervalo de bala 86 milissegundos

Recuo: [42, 36, 36, 36, 42, 43, 42, 43, 54, 55, 54, 55, 54, 55, 54, 55, 62, 62, 62, 62, 62, 62, 62, 62 ,62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 77, 78, 77, 78]

Indica a distância que precisa ser movida para baixo no eixo y depois que cada bala é disparada para neutralizar o recuo.

def moveMouse(): 
    #从识别的数据中,再更具当前选择的武器,获取此刻的武器(比如按下1键,武器装备栏1为m762,那么此时武器就是m762)
    curWepone = getCurrentWepone()
    if (curWepone.name == 'none'):
        return
    #基础y轴补偿(没任何配件)
    basic = curWepone.basic
    #射速
    speed = curWepone.speed
    startTime = round(time.perf_counter(), 3) * 1000
    for i in range(curWepone.maxBullets):
        #是否可以开火,比如左键抬起,就中断。
        if not canFire():
            break
        #系数,比如按住shift屏息,就需要再原来基础上乘1.33
        holdK = 1.0
        if c_contants.hold:
            holdK = curWepone.hold
        #乘以系数后实际的移动距离
        moveSum = int(round(basic[i] * curWepone.k * holdK, 2))
        while True:
            if (moveSum > 10):
                #移动鼠标
                pydirectinput.move(xOffset=0, yOffset=10, relative=True)
                moveSum -= 10
            elif (moveSum > 0):
                pydirectinput.move(xOffset=0, yOffset=moveSum, relative=True)
                moveSum = 0
            elapsed = (round(time.perf_counter(), 3) * 1000 - startTime)
            if not canFire() or elapsed > (i + 1) * speed + 10:
                break
            time.sleep(0.01)

loop while no código:

Na verdade, depois que a primeira bala é disparada, precisamos apenas descer uma distância de 42 e, em seguida, calcular o tempo de espera (0,086 - o tempo para mover o mouse), disparar a segunda bala e assim por diante.

A função do loop while é evitar que a tela trema muito. Como a distância de 42 é movida diretamente, o jogo treme muito, então movemos o mouse várias vezes em um intervalo de 86 milissegundos.

A função sleep em python não é precisa, então temos que cronometrar nós mesmos para evitar perder o intervalo de tempo de cada marcador. Existe outra vantagem de ser impreciso, aleatório, e acontece que você não precisa impedir a detecção por conta própria.

3. A parte mais problemática

O recuo de cada arma é diferente, precisamos ir sozinhos ao campo de treinamento do jogo, ajustar as balas uma a uma e obter dados de compensação precisos.

Quatro, finalmente

Envie o código para gitee e comunique-se com os interessados.

https://gitee.com/lookoutthebush/PUBG


Finalmente, gostaria de recomendar nosso grupo de membros. Atualmente, existem investidores anjo de capital de risco, headhunters HR, Douyin big V, blogueiros emocionais, advogados, conselheiros psicológicos, vendas médicas, imóveis, seguros, professores de piano, operadores, consultoria de negócios , Estudantes de comércio eletrônico transfronteiriço, construção, analistas de dados na indústria da Internet, desenvolvimento de back-end, teste de python e outras indústrias se juntarão.

Atualmente, existem mais de 400 pessoas no planeta e 41 truques foram atualizados no conteúdo da coluna. Todos os dias, os planetas publicam suas próprias experiências. Você pode aprender por apenas um dólar:

Python: 44 lições do curso introdutório de python + 9 lições da coluna Django + casos práticos interessantes

chatgpt: iniciante, avançado, fun office, cursos avançados

Pintura de IA: fundamentos de Mj, entrada, avançado, jogabilidade de Xiaohongshu

Você também pode conhecer muitas pessoas legais!

Junte-se para enviar uma conta independente do ChatGPT

80777f57d43135cd463ae71a58e771e1.jpeg

Envie também cursos em vídeo avançados do ChatGPT

O preço original é 99, e agora é grátis enviar membros do planeta

8f78b24544eb5453a7ac19ec44f7b112.jpeg

WeChat pressione e segure para experimentar o conteúdo

Se você não estiver satisfeito dentro de três dias, você pode reembolsar diretamente! ! !

b78a20403b9ddb1fc989b351407993d2.png

推荐阅读:
入门: 最全的零基础学Python的问题  | 零基础学了8个月的Python  | 实战项目 |学Python就是这条捷径
干货:爬取豆瓣短评,电影《后来的我们》 | 38年NBA最佳球员分析 |   从万众期待到口碑扑街!唐探3令人失望  | 笑看新倚天屠龙记 | 灯谜答题王 |用Python做个海量小姐姐素描图 |碟中谍这么火,我用机器学习做个迷你推荐系统电影
趣味:弹球游戏  | 九宫格  | 漂亮的花 | 两百行Python《天天酷跑》游戏!
AI: 会做诗的机器人 | 给图片上色 | 预测收入 | 碟中谍这么火,我用机器学习做个迷你推荐系统电影
小工具: Pdf转Word,轻松搞定表格和水印! | 一键把html网页保存为pdf!|  再见PDF提取收费! | 用90行代码打造最强PDF转换器,word、PPT、excel、markdown、html一键转换 | 制作一款钉钉低价机票提示器! |60行代码做了一个语音壁纸切换器天天看小姐姐!|

Acho que você gosta

Origin blog.csdn.net/cainiao_python/article/details/131118396
Recomendado
Clasificación