简介
最近写的一个基于Opencv视觉检测的游戏脚本(某炫舞2),可以辅助玩家在游戏中传统模式自动跳舞,通过对游戏画面的识别检测出目标需要按下的方向键或空格键,利用pynput模块模拟键盘操作来实现自动跳舞的效果。
实现过程
1.寻找游戏窗口并实时获取窗口大小,对游戏画面中的特定区域实时截图并其转换为灰度图像。
2.预先准备好的方向键和空格键的图片进行图案匹配,在游戏画面中检测出它们的位置。
3.根据匹配结果,按照从左到右的顺序依次模拟按下需要的按键,来实现自动跳舞的效果。
注意:游戏窗口大小要设置为:1280x720
import numpy as np
import win32gui
import mss, os
import cv2 as cv
from pynput.keyboard import Controller, Key
# @Author > 忆梦
# @Date > 2023/4/10
# @Project > QQ炫舞2 目标识别 - 自动跳舞(传统模式)
window_name = 'Auto'
path = "./img/"
threshold = 0.8 # 设置阈值为0.8
sct = mss.mss()
keyboard = Controller()
def press(keys):
keyboard.press(keys)
keyboard.release(keys)
template_data = [
{'name': 'right', 'file': 'right.png'},
{'name': 'left', 'file': 'left.png'},
{'name': 'up', 'file': 'up.png'},
{'name': 'down', 'file': 'down.png'},
{'name': 'space', 'file': 'en.png'},
]
keys = {
'right': Key.right,
'left': Key.left,
'up': Key.up,
'down': Key.down,
}
for tpl in template_data:
tpl['path'] = os.path.join(path, tpl['file'])
tpl['image'] = cv.imread(tpl['path'], cv.IMREAD_GRAYSCALE)
def main():
while True:
boxes = []
hwnd = win32gui.FindWindow(None, "QQ炫舞2")
cleft, ctop, cright, cbottom = win32gui.GetWindowRect(hwnd)
c_width, cheight = cright - cleft, cbottom - ctop
monitor = {
'left': cleft + 475,
'top': ctop + 481,
'width': c_width // 2 - 290,
'height': cheight // 2 - 294,
}
img = np.array(sct.grab(monitor))
game_area = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
for tpl in template_data:
template = tpl['image']
h, w = template.shape
res = cv.matchTemplate(game_area, template, cv.TM_CCOEFF_NORMED)
loc = np.where(res >= threshold)
found_pts = []
for pt in zip(*loc[::-1]):
center_pt = (pt[0] + w // 2, pt[1] + h // 2)
is_close_to_existing_point = False
for found_pt in found_pts:
if np.linalg.norm(np.array(center_pt) - np.array(found_pt)) < w // 2:
is_close_to_existing_point = True
break
if is_close_to_existing_point:
continue
found_pts.append(center_pt)
if tpl['name'] == "space":
if pt[0] >= 293 and pt[0] <= 320:
press(Key.space)
boxes.append({'name': tpl['name'], 'pt': pt})
cv.rectangle(
img, pt, (pt[0] + w, pt[1] + h), (0, 255, 255), 2)
boxes = sorted(boxes, key=lambda k: k['pt'][0])
found_names = [box['name'] for box in boxes]
for key in found_names:
if key != "space":
press(keys[key])
cv.imshow(window_name, img)
if cv.waitKey(1) & 0xFF == ord('q'):
break
cv.destroyAllWindows()
if __name__ == '__main__':
try:
main()
except Exception as e:
print(e)效果

评论 (0)