自己写的手机游戏脚本

由于过年时间特殊情况,在家特别无聊,就写了一个手机游戏的脚本
脚本所属游戏-战舰少女
功能很简单
● 自动刷活动材料
● 自动收获远征奖励
● 自动出征升级
● 自动分解船只
但是毕竟只是自己用的,选地图功能没有写,如果要用的话,还是需要自己先选好图,然后打开脚本。
逻辑有很多地方也需要改善。姑且这算是个砖吧,我也算是抛砖引玉,后续如果有哪位大神有兴趣的话,可以自己完善代码(别自己脸上贴金了,大佬哪会看上我这种代码啊 #手动捂脸)。
另外 func的那个是自己写的 文字识别功能,识别率不高就不贴上来了。功能就是根据坐标截取某一部分图片识别中间的文字,返回是识别到的文字。
注:本人第一次写手机游戏脚本,希望各位大神多提意见。
注2:里面的坐标是我一个一个试出来的。如果哪位大神有比较有效的方法获取坐标,也请不吝赐教,在下不胜感激。

import os
from time import sleep
import uiautomator2 as um
from PIL import Image, ImageFilter, ImageOps
from pytesseract import image_to_string

from func import get_text


class JianShao:
    def __init__(self):
        self.d = um.connect('127.0.0.1:62001')
        self.s_size = self.d.window_size()
        self.title = ('', '第一章', '第二章', '第三章', '第四章', '第五章', '第六章', '第七章', '第八章')
        self.is_food = 0  # 是否补给
        # self.is_fix = 0 # 是否修理
        self.is_resolve = 0  # 是否分解
        # self.d.window_size

    def start_app(self):
        '''登录游戏'''
        self.d.app_start('com.huanmeng.zhanjian2', 'org.cocos2dx.cpp.AppActivity')
        sleep(5)
        '''进入游戏页面'''
        while 1:
            self.click_grid(0.884, 0.871)
            sleep(2)
            if not self.text_in_screen(self.get_grid(0.818, 0.822, 0.946, 0.891), '进入游戏', 0):
                break

    def click_grid(self, x, y):
        """按指定的坐标点击屏幕"""
        self.d.click(int(self.s_size[1] * x), int(self.s_size[0] * y))

    def get_grid(self, x, y, x1, y1):
        """返回矩形位置"""
        return(self.s_size[1] * x, self.s_size[0] * y, self.s_size[1] * x1, self.s_size[0] * y1)
    
    def text_in_screen(self, grid, n_text, radius=1, lang='chi_sim'):
        """ 判断文字在不在图片里 grid: 截取的图片坐标(左上角x, 左上角y, 右下角x, 右下角y) radius: 高斯卷积核参数 为数字 lang: 识别语言 'chi_sim', 'eng' n_text: 需要判断的文字 """
        pic = self.d.screenshot()
        text = get_text(pic, grid, radius, lang)
        if n_text in text:
            return 1
        return 0

    def return_main(self):
        print('返回主界面')
        if not self.text_in_screen(self.get_grid(0.686, 0.924, 0.728, 0.96), '任务', radius=0.5):
            while True:
                self.click_grid(0.023, 0.041)
                sleep(0.5)
                if self.text_in_screen(self.get_grid(0.686, 0.924, 0.728, 0.96), '任务', radius=0.5):
                    self.click_grid(0.876, 0.22)
                    break
        self.click_grid(0.876, 0.22)

    def entry_map(self):
        """从主界面进入到地图界面"""
        print('点击出征')
        # punts_num = 0
        # 演习 radius=0 (1280*0.28, 720*0.022, 1280*0.34, 720*0.072)
        grid = self.get_grid(0.28, 0.022, 0.34, 0.072)
        while True:
            # 点击出征
            self.click_grid(0.946, 0.946)
            sleep(1)
            if self.text_in_screen(grid, '演习', 0):
                print('进到地图界面')
                break

    def expedition(self):
        '''获取远征奖励'''
        pic = self.d.screenshot()
        for i in range(4):
            end_time = get_text(pic, self.get_grid(0.84, 0.16+i/5, 0.97, 0.23+i/5), 0, 'eng')
            if end_time == '00:00:00':
                self.click_grid(0.9, 0.27+i/5)
                sleep(1.5)
                self.click_grid(0.4, 0.63)  # 和分解船只确定在一个地方
                sleep(1.5)
                print('点击确认')
                self.click_grid(0.4, 0.63)
                sleep(0.5)

    def army_ride(self, num, fix=0):
        """出征前准备 到补给完 num: 队伍编号 int 1,2,3,4 fix: 是否需要修理 0表示不修理 功能没写 换船功能也没写 """
        # if self.is_resolve >= 13:
        # print('需要分解船只')
        # self.resolve()
        # # 进入地图
        # self.entry_map()
        if self.is_resolve >=30:
            self.return_main()
            self.entry_map()
            self.is_resolve = 0
        # 判断是否在远征界面 
        while self.text_in_screen(self.get_grid(0.255, 0.26, 0.311, 0.315), f'奖励', 0):
            print('收获远征奖励')
            self.expedition()
            self.return_main()
            self.entry_map()
        # 判断有没有在队伍选择界面
        while 1:
            # 开始出征 radius=2 (1280*0.817, 720*0.887, 1280*0.932, 720*0.95)
            self.click_grid(0.638, 0.832)
            sleep(0.5)
            if self.text_in_screen(self.get_grid(0.817, 0.887, 0.932, 0.95), '开始出征', 2):
                break
        # 选择队伍
        army = ('', (0.1, 0.16), (0.23, 0.16), (0.36, 0.16), (0.48, 0.16))
        print(f'选择第{num}队')
        self.click_grid(*army[num])
        sleep(0.3)
        if self.is_food:
            self.click_grid(0.3, 0.79)
            sleep(0.3)
            print('点击补给')
            self.click_grid(0.85, 0.68)
            self.is_food = 0
            sleep(0.3)

    def go_on_ride(self):
        print('开始出征')
        while 1:
            self.click_grid(0.86, 0.881)
            sleep(0.5)
            if self.text_in_screen(self.get_grid(0.85, 0.9, 0.96, 0.96), '开始战斗'):
                print('遇到敌军')
                break
            print('没有遇到敌军')

    def get_back(self, title):
        """没有需要战斗的敌军,点击撤退 title: 正在战斗的章节 int 1, 2, 3, 4, 5, 6, 7, 8 """
        while 1:
            self.click_grid(0.68, 0.953)
            sleep(1)
            if self.text_in_screen(self.get_grid(0.035, 0.5, 0.113, 0.555), self.title[title], 0):
                break

    def fight_night(self, title, night=0, go_on=0):
        """ 结束战斗 title: 正在战斗的章数 int 1,2,3,4,5,6,7,8 night: 是否夜战 0不夜战 go_on: 前进/回港 0回港 """
        while 1:
            sleep(1.5)
            pic = self.d.screenshot()
            # pic.show()
            text1 = get_text(pic, self.get_grid(0.41, 0.025, 0.595, 0.125), 1.4)
            text2 = get_text(pic, self.get_grid(0.625, 0.625, 0.685, 0.685))
            if '战斗结果' in text1:
                print('战斗结束')
                break
            # 放弃 radius=1 (1280*0.63, 720*0.63, 1280*0.68, 720*0.68)
            if '放弃' in text2:
                if night:
                    print('进入夜战')
                    while 1:
                        self.click_grid(0.35, 0.66)
                        sleep(3)
                        if self.text_in_screen(self.get_grid(0.41, 0.025, 0.595, 0.125), '战斗结果', 1.4):
                            print('战斗结束')
                            break
                        print('战斗未结束')
                else:
                    print('战斗结束, 不夜战')
                    while 1:
                        self.click_grid(0.65, 0.66)
                        sleep(1.2)
                        if self.text_in_screen(self.get_grid(0.41, 0.025, 0.595, 0.125), '战斗结果', 1.4):
                            break
                break
            print('战斗未结束')
        while True:
            self.click_grid(0.65, 0.65)
            sleep(0.8)
            if self.text_in_screen(self.get_grid(0.035, 0.5, 0.113, 0.555), self.title[title], 0):
                print('返回到队伍界面')
                break

    def resolve(self):
        """分解船只,完成之后进入主界面"""
        print('准备分解战舰')
        self.return_main()
        while 1:
            self.click_grid(0.035, 0.9)
            sleep(0.5)
            print('点击建造(主页)')
            self.click_grid(0.035, 0.4)
            sleep(1)
            if self.text_in_screen(self.get_grid(0.28, 0.015, 0.338, 0.09), '解体'):
                print('点击解体')
                break
            print('未进入到建造界面')
            self.click_grid(0.5, 0.99)
            sleep(0.5)
        while 1:
            self.click_grid(0.3, 0.05)
            sleep(0.3)
            if self.text_in_screen(self.get_grid(0.825, 0.205, 0.96, 0.266), '解体获得资源'):
                print('点击添加')
                break
        while 1:
            self.click_grid(0.07, 0.35)
            sleep(0.5)
            if self.text_in_screen(self.get_grid(0.862, 0.02, 0.955, 0.072), '选择舰船'):
                print('开始添加')
                break
        ship_list = [(0.2, 0.3), (0.3, 0.3), (0.4, 0.3), (0.53, 0.3),(0.64, 0.3),(0.75, 0.3),
                     (0.08, 0.7), (0.2, 0.7), (0.3, 0.7), (0.4, 0.7), (0.53, 0.7),(0.64, 0.7),(0.75, 0.7)]
        for i in ship_list:
            self.click_grid(i[0], i[1])
        print('点击确定')
        while 1:
            self.click_grid(0.9, 0.9)
            sleep(0.5)
            if self.text_in_screen(self.get_grid(0.825, 0.205, 0.96, 0.266), '解体获得资源'):
                print('卸下装备')
                break
        self.click_grid(0.84, 0.66)
        print('确定解体')
        self.click_grid(0.9, 0.9)
        sleep(0.3)
        if self.text_in_screen(self.get_grid(0.353, 0.6, 0.416, 0.665), '确认', radius=2.5):
            self.click_grid(0.4, 0.64)
            sleep(0.3)
        self.is_resolve = 0
        self.return_main()

    def get_punts(self):
        '''2-1刷战利品'''
        self.entry_map()
        print('2-1')
        while 1:
            # print(f'刷到{punts_num}个材料')
            # 战斗前准备 选队-补给-出征-遇到敌军
            self.army_ride(2)
            self.go_on_ride()
            if not self.text_in_screen(self.get_grid(0.018, 0.442, 0.063, 0.495), '补给', 0):
                print('没有补给')
                self.get_back(2)
            else:
                print('准备战斗')
                while True:
                    self.click_grid(0.898, 0.928)
                    sleep(0.4)
                    # 选择阵型 radius=1 (1280*0.88, 720*0.06, 1280*0.995, 720*0.118)
                    if self.text_in_screen(self.get_grid(0.88, 0.06, 0.995, 0.118), '选择阵型'):
                        break
                print('选择复纵队')
                self.click_grid(0.836, 0.405)
                self.is_food = 1
                self.is_resolve += 1
                sleep(0.5)
                self.click_grid(0.922, 0.43)
                sleep(40)
                self.fight_night(2)

    def fishing(self):
        '''8-1炸鱼'''
        self.entry_map()
        # 进入8-1
        print('8-1')
        while 1:
            # 战斗前准备 选队-补给-出征-遇到敌军
            self.army_ride(4)
            self.go_on_ride()
            # (1280*0.03, 720*0.08, 1280*0.21, 720*0.17)
            if not self.text_in_screen(self.get_grid(0.03, 0.08, 0.21, 0.17), '复纵阵', radius=0):
                print('准备战斗')
                while True:
                    self.click_grid(0.898, 0.928)
                    sleep(0.4)
                    # 选择阵型 radius=1 (1280*0.88, 720*0.06, 1280*0.995, 720*0.118)
                    if self.text_in_screen(self.get_grid(0.88, 0.06, 0.995, 0.118), '选择阵型'):
                        break
                print('选择单横队')
                self.is_food = 1
                self.click_grid(0.928, 0.939)
                sleep(0.5)
                self.click_grid(0.898, 0.928)
                sleep(15)
                # 进入夜战,回港,返回第八章界面
                self.fight_night(8, 1, 0)
                self.is_resolve += 1
            else:
                print('敌方重巡, 撤退')
                self.get_back(8)
    
    def map_8_2(self):
        # 战前点击(选择战况)(0.828, 0.192, 0.918, 0.24) 火力万岁 点击(0.2, 0.65)
        # 遇到敌人 梯形队 (0.782, 0.74)
        # 不夜战
        self.entry_map()
        print('8-2')
        while 1:
            self.army_ride(3)
            print('开始出征')
            while 1:
                self.click_grid(0.86, 0.95)
                sleep(1)
                if self.text_in_screen(self.get_grid(0.828, 0.192, 0.918, 0.24), '火力万岁', 0):
                    print('遇到敌军')
                    while 1:
                        self.click_grid(0.2, 0.65)
                        sleep(1.2)
                        if self.text_in_screen(self.get_grid(0.85, 0.9, 0.96, 0.96), '开始战斗'):
                            print('准备战斗')
                            break
                    break
                print('没有遇到敌军')
            while 1:
                self.click_grid(0.898, 0.928)
                sleep(0.4)
                # 选择阵型 radius=1 (1280*0.88, 720*0.06, 1280*0.995, 720*0.118)
                if self.text_in_screen(self.get_grid(0.88, 0.06, 0.995, 0.118), '选择阵型'):
                    print('选择梯形队')
                    break
            while 1:
                self.click_grid(0.92, 0.76)
                sleep(2)
                if not self.text_in_screen(self.get_grid(0.88, 0.06, 0.995, 0.118), '选择阵型'):
                    break
            
            self.is_food = 1
            sleep(10)
            self.fight_night(8, 0, 0)
            self.is_resolve += 1

    原文作者:cnmnui
    原文地址: https://blog.csdn.net/cnmnui/article/details/104748793
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞