深度强化学习制作森林冰火人游戏AI获取游戏屏幕

Posted 怪皮蛇皮怪

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度强化学习制作森林冰火人游戏AI获取游戏屏幕相关的知识,希望对你有一定的参考价值。

概述

前篇:深度强化学习制作森林冰火人游戏AI(一)下载游戏
后篇:深度强化学习制作森林冰火人游戏AI(三)向游戏输出键盘控制信息

游戏有了,接下来是程序的输入了

获取窗口名称

windows里面的所有进程都有一个自己的名字(一知半解.jpg)

#获取窗口名字
def winEnumHandler(hwnd,non):
    if win32gui.IsWindowVisible(hwnd):
        name=win32gui.GetWindowText(hwnd)
        if name!='':
            print(hex(hwnd),name )

if __name__ == '__main__':
    win32gui.EnumWindows(winEnumHandler,None)

我们后续需要通过名字找到窗口的唯一handle(句柄),通过这个句柄我们才能获取窗口信息与发送控制命令

通过运行这段代码可以获得当前电脑里有界面的程序名字

0x1e0786 写文章-CSDN博客 和另外 9 个页面 - 用户配置 1 - Microsoft​ Edge
0x40608 FlashPlay
0x707fa Flash大厅
0x2305d4 CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US
0x1a019a 设置
0x102ee Microsoft Text Input Application
0x2016c Program Manager

我通过前一篇文章下载的flash大厅打开的游戏,所以自然而然的含有flash大厅这个进程
同时因为我已经打开了游戏,所以这里还有一个名叫FlashPlay(注意大小写)的进程,而这个名字便是游戏所在的窗口名字

获取窗口句柄

窗口句柄就像是进程唯一process id 一样,应该是每个窗口有唯一的handle
获取窗口句柄的方法

window_name="FlashPlay"
handle=windll.user32.FindWindowW(None, window_name)

嗯,就这么简单就获取了窗口句柄

获取窗口屏幕

这部分代码主体来自Python开发游戏自动化脚本(二)后台窗口客户区截图

同时因为后续深度强化学习需要用窗口屏幕作为每次训练的输入,这个输入大小会影响到训练的计算量的缘故。
博主在原有方法的基础上将其补充改造加入reshape方法,将窗口屏幕缩放至指定大小,通过减少屏幕分辨率来减少计算量

from ctypes import windll, byref, c_ubyte
from ctypes.wintypes import RECT, HWND

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np


class window_capture():
    def __init__(self,window_name,reshape_height,reshape_width):
        self.__handle = windll.user32.FindWindowW(None, window_name)
        self.__reshape_height=reshape_height
        self.__reshape_width=reshape_width

    def capture(self):
        """窗口客户区截图

        Args:
            handle (HWND): 要截图的窗口句柄

        Returns:
            numpy.ndarray: 截图数据
        """
        # 获取窗口客户区的大小
        r = RECT()
        windll.user32.SetProcessDPIAware()
        windll.user32.GetClientRect(self.__handle, byref(r))
        width, height = r.right, r.bottom
        # 开始截图
        dc = windll.user32.GetDC(self.__handle)
        cdc = windll.gdi32.CreateCompatibleDC(dc)
        bitmap = windll.gdi32.CreateCompatibleBitmap(dc, width, height)
        windll.gdi32.SelectObject(cdc, bitmap)
        windll.gdi32.BitBlt(cdc, 0, 0, width, height, dc, 0, 0, 0x00CC0020)
        # 截图是BGRA排列,因此总元素个数需要乘以4
        total_bytes = width*height*4
        buffer = bytearray(total_bytes)
        byte_array = c_ubyte*total_bytes
        windll.gdi32.GetBitmapBits(bitmap, total_bytes, byte_array.from_buffer(buffer))
        windll.gdi32.DeleteObject(bitmap)
        windll.gdi32.DeleteObject(cdc)
        windll.user32.ReleaseDC(self.__handle, dc)

        img_arr=np.frombuffer(buffer, dtype=np.uint8).reshape(height, width, 4)
        image_resize = Image.fromarray(img_arr).resize((self.__reshape_width,self.__reshape_height))
    
        return image_resize

if __name__ == "__main__":
    window_name='FlashPlay'
    win_c=window_capture(window_name,reshape_height=300,reshape_width=400)

    count=0
    while(count<1):
        count+=1
        photo=win_c.capture()
        print(photo)
        plt.imshow(photo)
        plt.pause(0.01)

后篇:深度强化学习制作森林冰火人游戏AI(三)向游戏输出键盘控制信息

以上是关于深度强化学习制作森林冰火人游戏AI获取游戏屏幕的主要内容,如果未能解决你的问题,请参考以下文章

深度强化学习制作森林冰火人游戏AI获取窗口部分界面

深度强化学习制作森林冰火人游戏AI识别游戏状态

深度强化学习制作森林冰火人游戏AI下载游戏

深度强化学习制作4399小游戏ai

教程 | 深度强化学习入门:用TensorFlow构建你的第一个游戏AI

使用深度 Q 学习的 AI 驱动蛇游戏 源码分享