深度强化学习制作森林冰火人游戏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获取游戏屏幕的主要内容,如果未能解决你的问题,请参考以下文章