本文为基于pyautogui、tkinter以及几个标准库开发的用于传奇3法师自动练级的python脚本,代码编写并不完美,只是将本人业余学的python正好运用到了实践当中,有了兴趣的趋动,最终能成功运行,权当是python练手一用。

接上篇博文《【实战项目记录1】编写一个传奇3法师自动练级的python脚本》

今天发布剩下的模块:初始化模块mir3_init.py;遇敌判断模块mir3_is_enemy.py;捡物品模块:mir3_is_item.py

大部分都是借助了pyautogui的控制键鼠功能和图片识别功能,个人觉得比较难的是设置行动范围和规划捡物品路线,供参考。

1.初始化模块mir3_init.py

#!/usr/bin/env python

# -*- coding:utf-8 -*-

# @Time      :2022-5-4 0:08

# @Author    :Mengxh

# @File      :mir3_init.py
import os

# 装备图库载入列表
itemlist = []
for root, dirs, files in os.walk("./pics/pickup", topdown=False):
    for name in files:
        itemlist.append(os.path.join(root, name))

# 定义逐点行走方向和鼠标左右键
l = 350  # x = 100左
r = 700  # x = 900右
u = 200  # y = 150上
d = 500  # y = 550下
role_x = 503  # 人物中心点x坐标
role_y = 353  # 人物中心点y坐标
x_list = [x for x in range(23,1031,48)]
y_list = [x for x in range(65,641,32)]
lu = (l, u)  # 左上
ld = (l, d)  # 左下
ru = (r, u)  # 左上
rd = (r, d)  # 左上
move_list_u = [lu, ru]
move_list_d = [ld, rd]
move_list = move_list_d + move_list_u
region_0 = (1052, 67, 362, 214)  # 大补贴截屏范围
region_main = (21, 51, 1000, 730)  # 游戏主画面范围
region_jq = (903, 30, 120, 125)
jq_pos = (975, 105)
print('行走方向设置完成')
print('主游戏画面区域设置完成')

if __name__ == '__main__':
    print(x_list)
    print(y_list)

2.遇敌判断模块mir3_is_enemy.py

#!/usr/bin/env python

# -*- coding:utf-8 -*-

# @Time      :2022-5-3 23:49

# @Author    :Mengxh

# @File      :mir3_is_enemy.py
import time
import pyautogui
import mir3_init
pyautogui.PAUSE = 1


def is_enemy():
    t = pyautogui.locateOnScreen('./pics/locatepng/guaiwu.png', region=mir3_init.region_0, confidence=0.7)
    if t is not None:
        return True
        # for i in range(2):
        #     pyautogui.press('f2', interval=0.5)
        # im_1 = pyautogui.locateOnScreen('./pics/menupng/kouxue.png', region=mir3_init.region_main, confidence=0.9)
        # im_2 = pyautogui.locateOnScreen('./pics/menupng/kouxue.png', region=mir3_init.region_main, confidence=0.9)
        # if im_1 or im_2:
        #     # print('打了有怪')
        #     return True
        # else:
        #     # print('打了无怪')
        #     return False
    else:
        # print('信息无怪')
        return False


if __name__ == '__main__':
    time.sleep(2)
    is_enemy()

3.捡物品模块:mir3_is_item.py

#!/usr/bin/env python

# -*- coding:utf-8 -*-

# @Time      :2022-5-3 23:30

# @Author    :Mengxh

# @File      :mir3_is_item.py

import pyautogui
import mir3_init
import threading
import pandas as pd

# 对比标准x,y坐标列表,重新设置物品标准坐标
def compare_xy(a,b):
    x = mir3_init.x_list[list(map(lambda x: abs(x - a), mir3_init.x_list)).index(min(list(map(lambda x: abs(x - a), mir3_init.x_list))))]
    y = mir3_init.y_list[list(map(lambda x: abs(x - b), mir3_init.y_list)).index(min(list(map(lambda x: abs(x - b), mir3_init.y_list))))]
    return x,y

def is_item(item, pos_list):
    ts = pyautogui.locateAllOnScreen('%s' % item, region=mir3_init.region_main, confidence=0.6)
    if ts is not None:
        for t in ts:
            pos = pyautogui.center(t)
            pos = compare_xy(pos.x,pos.y)
            pos_list.append(pos)

def move_line(pos_list):
    pos0 = (mir3_init.role_x,mir3_init.role_y)
    df = pd.DataFrame(pos_list, columns=['x', 'y'], dtype='int32')
    df['s'] = ((df['x'] - pos0[0]) ** 2 + (df['y'] - pos0[1]) ** 2) ** 0.5
    newpos_list = []
    while True:
        i = df['s'].idxmin()
        newpos_list.append((int(df.loc[i][0]),int(df.loc[i][1])))

        delta_x = pos0[0] - df.loc[i][0]
        delta_y = pos0[1] - df.loc[i][1]
        df = df.drop(index=[i])

        df['x'] = df['x'] + delta_x
        df['y'] = df['y'] + delta_y


        df['s'] = ((df['x'] - pos0[0]) ** 2 + (df['y'] - pos0[1]) ** 2) ** 0.5
        if df.shape[0] == 0:
            return newpos_list

def multi_thread():
    print('开始扫描装备')
    threads = []
    pos_list= []
    for item in mir3_init.itemlist:
        threads.append(
            threading.Thread(target=is_item, args=(item, pos_list))
        )

    for thread in threads:
        thread.start()

    for thread in threads:
        thread.join()

    print('结束扫描装备')
    if pos_list:
        pos_list = move_line(pos_list)
    print(pos_list)
    return pos_list

if __name__ == '__main__':
    while True:
        multi_thread()

最后比较遗憾的是,这个脚本必须在前台运行,电脑就只能挂机,干不了别的事。自己本想用pywin32尝试后台控制,但因为本人非专业人士,不懂Windows编程,尝试最终也是失败。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐