精华内容
下载资源
问答
  • 如何写脚本让游戏自己
    万次阅读 多人点赞
    2020-03-09 11:46:27

    由于过年时间特殊情况,在家特别无聊,就写了一个手机游戏的脚本
    脚本所属游戏-战舰少女
    功能很简单
    ● 自动刷活动材料
    ● 自动收获远征奖励
    ● 自动出征升级
    ● 自动分解船只
    但是毕竟只是自己用的,选地图功能没有写,如果要用的话,还是需要自己先选好图,然后打开脚本。
    逻辑有很多地方也需要改善。姑且这算是个砖吧,我也算是抛砖引玉,后续如果有哪位大神有兴趣的话,可以自己完善代码(别自己脸上贴金了,大佬哪会看上我这种代码啊 #手动捂脸)。
    另外 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
    
    
    更多相关内容
  • 用shell脚本写一个猜数游戏 最近用shell的一个猜数游戏,包括4个不同难度,脚本如下: #作者:p_小王 echo '欢迎来到猜数游戏!' while true do read -p '开始/退出(y/n):' x #提示用户输入 if [ -z $x ] #...
  • 易语言-易语言游戏脚本写法源码
  • java能写游戏脚本吗?

    千次阅读 2021-02-12 11:37:18
    java能写游戏脚本。Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征,可以做到编译游戏脚本。java能写游戏脚本...

    java能写游戏脚本。Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征,可以做到编译游戏脚本。

    5aa2e9bc54a1b5dc80359110170412ce.png

    java能写游戏脚本。

    Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。

    Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程 。

    Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点 。Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等 。

    特点:

    1.简单性

    Java看起来设计得很像C++,但是为了使语言小和容易熟悉,设计者们把C++语言中许多可用的特征去掉了,这些特征是一般程序员很少使用的。例如,Java不支持go to语句,代之以提供break和continue语句以及异常处理。

    Java还剔除了C++的操作符过载(overload)和多继承特征,并且不使用主文件,免去了预处理程序。

    因为Java没有结构,数组和串都是对象,所以不需要指针。Java能够自动处理对象的引用和间接引用,实现自动的无用单元收集,使用户不必为存储管理问题烦恼,能更多的时间和精力花在研发上。

    2.面向对象

    Java是一个面向对象的语言。对程序员来说,这意味着要注意应中的数据和操纵数据的方法(method),而不是严格地用过程来思考。在一个面向对象的系统中,类(class)是数据和操作数据的方法的集合。

    数据和方法一起描述对象(object)的状态和行为。每一对象是其状态和行为的封装。类是按一定体系和层次安排的,使得子类可以从超类继承行为。在这个类层次体系中有一个根类,它是具有一般行为的类。Java程序是用类来组织的。

    Java还包括一个类的扩展集合,分别组成各种程序包(Package),用户可以在自己的程序中使用。例如,Java提供产生图形用户接口部件的类(java.awt包),这里awt是抽象窗口工具集(abstract windowing toolkit)的缩写,处理输入输出的类(java.io包)和支持网络功能的类(java.net包)。

    3.分布性

    Java设计成支持在网络上应用,它是分布式语言。Java既支持各种层次的网络连接,又以Socket类支持可靠的流(stream)网络连接,所以用户可以产生分布式的客户机和服务器。

    网络变成软件应用的分布运载工具。Java程序只要编写一次,就可到处运行。

    4.编译和解释性

    Java编译程序生成字节码(byte-code),而不是通常的机器码。Java字节码提供对体系结构中性的目标文件格式,代码设计成可有效地传送程序到多个平台。Java程序可以在任何实现了Java解释程序和运行系统(run-time system)的系统上运行。

    在一个解释性的环境中,程序开发的标准“链接”阶段大大消失了。如果说Java还有一个链接阶段,它只是把新类装进环境的过程,它是增量式的、轻量级的过程。因此,Java支持快速原型和容易试验,它将导致快速程序开发。

    这是一个与传统的、耗时的“编译、链接和测试”形成鲜明对比的精巧的开发过程。

    5.稳健性

    Java

    Java原来是用作编写消费类家用电子产品软件的语言,所以它是被设计成写高可靠和稳健软件的。Java消除了某些编程错误,使得用它写可靠软件相当容易。

    Java是一个强类型语言,它允许扩展编译时检查潜在类型不匹配问题的功能。Java要求显式的方法声明,它不支持C风格的隐式声明。这些严格的要求保证编译程序能捕捉调用错误,这就导致更可靠的程序。

    可靠性方面最重要的增强之一是Java的存储模型。Java不支持指针,它消除重写存储和讹误数据的可能性。类似地,Java自动的“无用单元收集”预防存储漏泄和其它有关动态存储分配和解除分配的有害错误。

    Java解释程序也执行许多运行时的检查,诸如验证所有数组和串访问是否在界限之内。

    异常处理是Java中使得程序更稳健的另一个特征。异常是某种类似于错误的异常条件出现的信号。使用try/catch/finally语句,程序员可以找到出错的处理代码,这就简化了出错处理和恢复的任务。

    6.安全性

    Java的存储分配模型是它防御恶意代码的主要方法之一。Java没有指针,所以程序员不能得到隐蔽起来的内幕和伪造指针去指向存储器。

    更重要的是,Java编译程序不处理存储安排决策,所以程序员不能通过查看声明去猜测类的实际存储安排。编译的Java代码中的存储引用在运行时由Java解释程序决定实际存储地址。

    Java运行系统使用字节码验证过程来保证装载到网络上的代码不违背任何Java语言限制。这个安全机制部分包括类如何从网上装载。例如,装载的类是放在分开的名字空间而不是局部类,预防恶意的小应用程序用它自己的版本来代替标准Java类。

    7.可移植性

    Java使得语言声明不依赖于实现的方面。例如,Java显式说明每个基本数据类型的大小和它的运算行为(这些数据类型由Java语法描述)。

    Java环境本身对新的硬件平台和操作系统是可移植的。Java编译程序也用Java编写,而Java运行系统用ANSIC语言编写。

    8.高性能

    Java是一种先编译后解释的语言,所以它不如全编译性语言快。

    但是有些情况下性能是很要紧的,为了支持这些情况,Java设计者制作了“及时”编译程序,它能在运行时把Java字节码翻译成特定CPU(中央处理器)的机器代码,也就是实现全编译了。

    Java字节码格式设计时考虑到这些“及时”编译程序的需要,所以生成机器代码的过程相当简单,它能产生相当好的代码。

    9.多线程性

    Java是多线程语言,它提供支持多线程的执行(也称为轻便过程),能处理不同任务,使具有线索的程序设计很容易。Java的lang包提供一个Thread类,它支持开始线索、运行线索、停止线索和检查线索状态的方法。

    Java的线索支持也包括一组同步原语。这些原语是基于监督程序和条件变量风范,由C.A.R.Haore开发的广泛使用的同步化方案。用关键词synchronized,程序员可以说明某些方法在一个类中不能并发地运行。

    这些方法在监督程序控制之下,确保变量维持在一个一致的状态。

    10.动态性

    Java语言设计成适应于变化的环境,它是一个动态的语言。例如,Java中的类是根据需要载入的,甚至有些是通过网络获取的。

    推荐教程:《java教程》

    展开全文
  • 那么这周我就篇文章从游戏脚本聊起,分析一下游戏脚本因何出现,而Mono又能提供怎样的脚本基础。最后会通过模拟Unity3D游戏引擎中的脚本功能,将Mono运行时嵌入到一个非托管(C/C++)程序中,实现脚本语言和“引擎...
  • 由于阴阳师这个游戏肝度太大,就决定一个脚本来模拟玩家的重复性操作.所以我就决定用java中的robot类中的一些方法来模拟鼠标点击,移动等功能,具体方法见下图. 因为一个好看的界面能人看着更加的舒服,所以就决定用...
  • 自己写的一款键盘鼠标脚本记录工具,可以用来游戏里挂机,人物自动行走打怪。
  • 怎么写游戏脚本.docx

    2021-11-15 13:08:03
    怎么写游戏脚本.docx
  • 用Python写游戏脚本原来这么简单

    千次阅读 2021-12-30 20:41:00
    游戏脚本其实并不高深,最简单的体验方法就是下载一个Airtest了,直接截几个图片,几层代码,就可以按照自己的逻辑玩儿游戏了。 当然,本篇文章不是要讲Airtest这个怎么用,而是用原始的python+opencv来实现...

    游戏这种东西完全可以用写代码的方式帮我们自动完成。游戏脚本其实并不高深,最简单的体验方法就是下载一个Airtest了,直接截几个图片,写几层代码,就可以按照自己的逻辑玩儿游戏了。

    当然,本篇文章不是要讲Airtest这个怎么用,而是用原始的python+opencv来实现上面的操作。

    这两天我写了一个公主连结刷初始号的程序,也不能算写游戏脚本的老手,这篇文章主要是分享一些基础的技术和使用上的心得吧。

    准备工作

    首先,我们要完成以下准备。

    安卓设备一个:模拟器或者真机都可以。

    安装ADB,并添加到系统的PATH里:adb是用来

    安装tesseract-ocr,并添加到系统的PATH里:帮助我们实现简单的字符识别

    安装python3.7以上的版本

    这里adb和tesseract我放在百度网盘里了,里面顺便放了一个录制的效果视频。

    链接:pan.baidu.com/s/1edTPu2o7… 提取码:33aw

    python库安装

    pipinstall pillow pytesseract opencv-python复制代码

    除此以外,如果有需要可以安装uiautomator2,这篇文章就不涉及这块知识了。

    使用adb获取安卓设备

    这里我们主要是涉及到单个安卓设备的ADB连接操作,首先我们打开模拟器。

    然后我们调用adb devices来获取当前的安卓设备,我这里是一个模拟器。

    接下来可以调用adb shell测试一下是否能进入到安卓设备的shell环境下,确认可以输入exit退出即可。

    如果有的时候进不了shell,可以先调用一下adb kill-server,然后再调用adb devices。

    可能常用的ADB Shell命令

    接下来是一些ADB的命令操作。通过adb命令,我们可以用python来操作的安卓设备。

    屏幕截图

    最常见的操作就是截图了,先调用screencap截图放到安卓设备里,然后再把截图下拉到电脑。

    def take_screenshot():  
        os.system("adb shell screencap -p /data/screenshot.png")  
        os.system("adb pull /data/screenshot.png ./tmp.png") 
    

    下拉文件

    下拉文件就是刚刚那个adb pull了,以公主连结为例,以下代码可以导出账号信息的xml,以后通过xml就可以登录了。

    os.system(f"adb pull /data/data/tw.sonet.princessconnect/shared_prefs/tw.sonet.princessconnect.v2.playerprefs.xml ./user_info.xml") 
    

    上传文件

    有了下拉自然就有上传了,通过adb push即可完成。以公主连结为例,以下代码可以完成账号的切换。

    # 切换账号1  
    os.system("adb push ./user_info1.xml /data/data/tw.sonet.princessconnect/shared_prefs/tw.sonet.princessconnect.v2.playerprefs.xml")  
    # 切换账号2 
    os.system("adb push ./user_info2.xml /data/data/tw.sonet.princessconnect/shared_prefs/tw.sonet.princessconnect.v2.playerprefs.xml") 
    

    点击屏幕某个位置

    def adb_click(center, offset=(0, 0)):  
        (x, y) = center  
        x += offset[0]  
        y += offset[1]  
        os.system(f"adb shell input tap {x} {y}") 
    

    输入文字

    text = "YourPassword"  
    os.system(f"adb shell input text {text}") 
    

    删除字符

    有的时候输入框会有输入的缓存,我们需要删除字符。

    # 删除10个字符  
    for i in range(10):  
        os.system("adb shell input keyevent 67") 
    

    查询当前运行的包名和Activity

    通过以下代码,可以查询当前运行的程序的Activity,也可以顺便查包名。

    adb shell dumpsys activity activities 
    

    停止某个应用

    有时候会需要停止某个应用,需要提供应用的包名。

    adb shell am force-stop tw.sonet.princessconnect 
    

    开启某个应用

    开启某个应用需要提供包名以及Activity。

    adb shell am start -W -n tw.sonet.princessconnect/jp.co.cygames.activity.OverrideUnityActivity 
    

    图像操作

    对于图像的操作第一就是图像查找了,比如说像Airtest提供的这种,无非就是判断某个图像在不在截屏中,在的话在什么位置。

    除此之外还需要一些抠图,比如说我们想获取账号的id,账号的等级,需要截取出一部分图片然后进行OCR操作。

    图像查找

    图像查找其实就是先拿到两张图片,然后调用cv2.matchTemplate方法来查找是否存在以及位置,这里匹配是一个相对模糊的匹配,会有一个相似度的概率,最高是1。我们设定一个阈值来判断模板是否在截屏里即可。

    这里截屏如下,文件名为tmp.png:

    模板如下:

    代码如下:

    import cv2  
    def image_to_position(screen, template):  
        image_x, image_y = template.shape[:2]  
        result = cv2.matchTemplate(screen, template, cv2.TM_CCOEFF_NORMED)  
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)  
        print("prob:", max_val)  
        if max_val > 0.98:  
            global center  
            center = (max_loc[0] + image_y / 2, max_loc[1] + image_x / 2)  
            return center  
        else:  
            return False  
    if __name__ == "__main__":  
        screen = cv2.imread('tmp.png')  
        template =  cv2.imread('Xuandan.png')  
        print(image_to_position(screen, template)) 
    

    运行上述代码后,可以看到模板匹配出来的概率为0.9977,位置为(1165, 693),对于一张图片,左上角为原点,因为我的分辨率是1280 * 720,那么右下角的坐标就是(1280, 720)。可以看到我们这个选单其实就是刚好在右下角的位置。

    如何快速裁剪模板?(win10)

    游戏脚本其实并不是代码很难写,而是需要截很多的图,这些图要保证分辨率和原始一样。我发现在win10如果用画图打开图片

    可以保证使用QQ截屏出来的分辨率,和图片本身的分辨率一样。

    这个时候直接用qq截屏出来的模板即可直接用于识别。

    图像裁剪

    接下来就是有时候需要裁剪一些图像了,当然我们的模板图片也可以通过裁剪图片的方式得到,这样的模板图片是最准的。

    裁剪其实就是需要裁剪的位置,以及需要的高度和宽度,说白了就是一篇长方形的区域,下面的代码使用PIL库实现。

    from PIL import Image  
    def crop_screenshot(img_file, pos_x, pos_y, width, height, out_file):  
        img = Image.open(img_file)  
        region = (pos_x, pos_y, pos_x + width, pos_y + height)  
        cropImg = img.crop(region)  
        cropImg.save(out_file)  
        print("exported:", out_file)  
    if __name__ == "__main__":  
        crop_screenshot("tmp.png", 817,556, 190, 24, "test_id.png") 
    

    上面的代码以截取玩家的id为例。

    运行代码后,得到截图如下:

    简单的OCR

    得到了以上的图片信息后就是进行OCR了,也就是光学字符识别。这里代码非常简单,只要调用API即可。

    from PIL import Image  
    import pytesseract  
    image = Image.open('test_id.png')  
    content = pytesseract.image_to_string(image)   # 识别图片  
    print(content) 
    

    不过需要注意的一点就是pytesseract识别出来的结果会有空格符,换行符这样的符号,真正要用的时候进行一些字符的过滤即可。

    The End

    这篇文章到这里就结束了,主要还是介绍一些ADB以及图像相关的基础操作。谢谢大家的观看。

    如果大家想学习python或者想要python免费资料的话可扫码获取 

     

    展开全文
  • 用python写游戏脚本原来这么简单

    千次阅读 2021-11-12 09:49:39
    游戏脚本其实并不高深,最简单的体验方法就是下载一个Airtest了,直接截几个图片,几层代码,就可以按照自己的逻辑玩儿游戏了。 当然,本篇文章不是要讲Airtest这个怎么用,而是用原始的python+opencv来实现...

    前言

    最近在玩儿公主连结,之前也玩儿过阴阳师这样的游戏,这样的游戏都会有个初始号这样的东西,或者说是可以肝的东西。

    当然,作为一名程序员,肝这种东西完全可以用写代码的方式帮我们自动完成。游戏脚本其实并不高深,最简单的体验方法就是下载一个Airtest了,直接截几个图片,写几层代码,就可以按照自己的逻辑玩儿游戏了。

    当然,本篇文章不是要讲Airtest这个怎么用,而是用原始的python+opencv来实现上面的操作。

    这两天我写了一个公主连结刷初始号的程序,也不能算写游戏脚本的老手,这篇文章主要是分享一些基础的技术和使用上的心得吧。

    准备工作

    首先,我们要完成以下准备。

    • 安卓设备一个:模拟器或者真机都可以。
    • 安装ADB,并添加到系统的PATH里:adb是用来
    • 安装tesseract-ocr,并添加到系统的PATH里:帮助我们实现简单的字符识别
    • 安装python3.7以上的版本

    这里adb和tesseract我放在百度网盘里了,里面顺便放了一个录制的效果视频。

    链接:https://pan.baidu.com/s/1iBigCLt-ts_jUBDyd1gUCg
    提取码:qwe1

    python库安装

    pip install pillow pytesseract opencv-python
    复制代码

    除此以外,如果有需要可以安装uiautomator2,这篇文章就不涉及这块知识了。

    使用adb获取安卓设备

    这里我们主要是涉及到单个安卓设备的ADB连接操作,首先我们打开模拟器。

    然后我们调用adb devices来获取当前的安卓设备,我这里是一个模拟器。

    接下来可以调用adb shell测试一下是否能进入到安卓设备的shell环境下,确认可以输入exit退出即可。

    如果有的时候进不了shell,可以先调用一下adb kill-server,然后再调用adb devices

    可能常用的ADB Shell命令

    接下来是一些ADB的命令操作。通过adb命令,我们可以用python来操作的安卓设备。

    屏幕截图

    最常见的操作就是截图了,先调用screencap截图放到安卓设备里,然后再把截图下拉到电脑。

    def take_screenshot():
        os.system("adb shell screencap -p /data/screenshot.png")
        os.system("adb pull /data/screenshot.png ./tmp.png")
    复制代码

    下拉文件

    下拉文件就是刚刚那个adb pull了,以公主连结为例,以下代码可以导出账号信息的xml,以后通过xml就可以登录了。

    os.system(f"adb pull /data/data/tw.sonet.princessconnect/shared_prefs/tw.sonet.princessconnect.v2.playerprefs.xml ./user_info.xml")
    复制代码

    上传文件

    有了下拉自然就有上传了,通过adb push即可完成。以公主连结为例,以下代码可以完成账号的切换。

    # 切换账号1
    os.system("adb push ./user_info1.xml /data/data/tw.sonet.princessconnect/shared_prefs/tw.sonet.princessconnect.v2.playerprefs.xml")
    
    # 切换账号2
    os.system("adb push ./user_info2.xml /data/data/tw.sonet.princessconnect/shared_prefs/tw.sonet.princessconnect.v2.playerprefs.xml")
    复制代码

    点击屏幕某个位置

    def adb_click(center, offset=(0, 0)):
        (x, y) = center
        x += offset[0]
        y += offset[1]
        os.system(f"adb shell input tap {x} {y}")
    复制代码

    输入文字

    text = "YourPassword"
    os.system(f"adb shell input text {text}")
    复制代码

    删除字符

    有的时候输入框会有输入的缓存,我们需要删除字符。

    # 删除10个字符
    for i in range(10):
        os.system("adb shell input keyevent 67")
    复制代码

    查询当前运行的包名和Activity

    通过以下代码,可以查询当前运行的程序的Activity,也可以顺便查包名。

    adb shell dumpsys activity activities
    复制代码

    停止某个应用

    有时候会需要停止某个应用,需要提供应用的包名。

    adb shell am force-stop tw.sonet.princessconnect
    复制代码

    开启某个应用

    开启某个应用需要提供包名以及Activity。

    adb shell am start -W -n tw.sonet.princessconnect/jp.co.cygames.activity.OverrideUnityActivity
    复制代码

    图像操作

    对于图像的操作第一就是图像查找了,比如说像Airtest提供的这种,无非就是判断某个图像在不在截屏中,在的话在什么位置。

    除此之外还需要一些抠图,比如说我们想获取账号的id账号的等级,需要截取出一部分图片然后进行OCR操作。

    图像查找

    图像查找其实就是先拿到两张图片,然后调用cv2.matchTemplate方法来查找是否存在以及位置,这里匹配是一个相对模糊的匹配,会有一个相似度的概率,最高是1。我们设定一个阈值来判断模板是否在截屏里即可。

    这里截屏如下,文件名为tmp.png

    模板如下:

    代码如下:

    import cv2
    
    def image_to_position(screen, template):
        image_x, image_y = template.shape[:2]
        result = cv2.matchTemplate(screen, template, cv2.TM_CCOEFF_NORMED)
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
        print("prob:", max_val)
        if max_val > 0.98:
            global center
            center = (max_loc[0] + image_y / 2, max_loc[1] + image_x / 2)
            return center
        else:
            return False
    
    if __name__ == "__main__":
        screen = cv2.imread('tmp.png')
        template =  cv2.imread('Xuandan.png')
        print(image_to_position(screen, template))
    复制代码

    运行上述代码后,可以看到模板匹配出来的概率为0.9977,位置为(1165, 693),对于一张图片,左上角为原点,因为我的分辨率是1280 * 720,那么右下角的坐标就是(1280, 720)。可以看到我们这个选单其实就是刚好在右下角的位置。

    如何快速裁剪模板?(win10)

    游戏脚本其实并不是代码很难写,而是需要截很多的图,这些图要保证分辨率和原始一样。我发现在win10如果用画图打开图片

    可以保证使用QQ截屏出来的分辨率,和图片本身的分辨率一样。

    这个时候直接用qq截屏出来的模板即可直接用于识别。

    图像裁剪

    接下来就是有时候需要裁剪一些图像了,当然我们的模板图片也可以通过裁剪图片的方式得到,这样的模板图片是最准的。

    裁剪其实就是需要裁剪的位置,以及需要的高度和宽度,说白了就是一篇长方形的区域,下面的代码使用PIL库实现。

    from PIL import Image
    
    def crop_screenshot(img_file, pos_x, pos_y, width, height, out_file):
        img = Image.open(img_file)
        region = (pos_x, pos_y, pos_x + width, pos_y + height)
        cropImg = img.crop(region)
        cropImg.save(out_file)
        print("exported:", out_file)
    
    if __name__ == "__main__":
        crop_screenshot("tmp.png", 817,556, 190, 24, "test_id.png")
    
    复制代码

    上面的代码以截取玩家的id为例。

    运行代码后,得到截图如下:

    简单的OCR

    得到了以上的图片信息后就是进行OCR了,也就是光学字符识别。这里代码非常简单,只要调用API即可。

    from PIL import Image
    import pytesseract
    
    image = Image.open('test_id.png')
    content = pytesseract.image_to_string(image)   # 识别图片
    print(content)
    
    复制代码

    不过需要注意的一点就是pytesseract识别出来的结果会有空格符,换行符这样的符号,真正要用的时候进行一些字符的过滤即可。

    The End

    这篇文章到这里就结束了,主要还是介绍一些ADB以及图像相关的基础操作,有些内容比如说多开和uiautomator2因为我暂时没用到所以就没写,百度一下应该也不是很难。代码写的比较丑还没完善好,就先不放了。


     

    展开全文
  • 脚本游戏2048

    2018-07-31 20:31:06
    大神的2048小游戏,很适合程序员用来装逼(咳咳,研究)
  • 发现好多易友看不懂代码 或者 不知道是什么东西。抽空了个简单的例子出来。
  • 用Python一个游戏脚本,你会吗?

    千次阅读 2020-11-24 12:48:19
    裙 :一久武其而而流一思(数字的谐音)转换下可以找到了,里面有最新Python教程项目听说pywin32写脚本还不错pywin32主要代码我以楚留香的电脑版为例,记录脚本的编写之路吧。因为主要游戏都在windows跑,没什么好说...
  • 一个用lua游戏脚本实例

    热门讨论 2010-04-19 13:28:03
    一个用lua游戏脚本实例,是word格式的,值得一看,通过这个例子你可以了解到游戏中的脚本是怎么
  • 游戏简易脚本制作教程

    千次阅读 2021-05-23 03:47:50
    马上注册,结交更多易友,享用更多功能,你轻松玩转觅风论坛。...来看看什么是游戏脚本游戏脚本是一个工具,这个工具可以实现的功能是模拟人手的行为来自动进行游戏。说到这你可能还有些不懂,但是没关系,接下...
  • pythonlol游戏脚本俾格米人和搅拌机的引擎。python-ogre和panda3d是用c/c编写的,但只提供了一个python接口。 你好,蟒蛇可以在Android上工作。 因为你可以在Android上安装一个pythonruntime,这就行了! 就像...
  • 如何用python写游戏脚本

    千次阅读 多人点赞 2020-08-17 13:43:08
    前言 最近在玩儿公主连结,之前也玩儿过阴阳师这样的游戏,这样的游戏都会有个初始号这样的东西,或者说是可以肝的东西。 很多人学习python,不知道从何学起。 很多人学习python,掌握...游戏脚本其实并不高深,最简
  • 易语言自定义执行源码.zip,易语言自定义执行源码,脚本.e
  • 游戏脚本开发实战

    千次阅读 2021-07-06 10:44:38
    随着现在游戏越来越多,游戏脚本也越来越多。脚本和外挂是有区别的。 外挂:通过对内存有读或操作,以实现自动挂机,违反法律(破坏计算机信息系统罪)。 脚本:通过对图色的识别,模拟人手对鼠标或键盘进行操作...
  • 易语言轩辕传奇脚本源码
  • from Win32_Process Where ProcessId='" & PID & "'") For Each objProcess in colProcessList objProcess.Terminate() Next WScript.Echo "Close ProcessId='" & PID & "'" 2.Word加载项中的登记函数 要想Word中...
  • LUA梦幻西游互通版抓鬼简写,一个简单的抓鬼LUA,用触动精灵的。
  • 适用于写游戏脚本,简单粗暴!
  • 对于有兴趣学习游戏脚本的同学有一定的帮助。运行环境:Win10/Python3.5。主要模块:win32gui(识别窗口、窗口置顶等操作)、PIL(屏幕截图)、numpy(创建矩阵)、operator(比较值)、pymouse(模拟鼠标点击)。...
  • 游戏脚本的故事

    2012-12-28 12:15:02
    用于游戏脚本的制作指南。本来用于电影,但对关卡设计有一定参考价值。
  • Java游戏脚本实现

    千次阅读 2021-07-26 09:06:50
    思路 ... 借助模拟器的快捷键位设置就可以将坐标相对化。下图是雷电模拟器例子 可以看到图中的快捷键。 最后便是如果Robot要执行模拟器中对应的快捷键,有个前提条件:该模拟器窗口必须位于当前窗口。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 93,440
精华内容 37,376
热门标签
关键字:

如何写脚本让游戏自己