美文网首页
用Python实现阴阳师自动抽卡

用Python实现阴阳师自动抽卡

作者: Meowcolm024 | 来源:发表于2018-08-19 17:28 被阅读0次

    1. 想法

    突然想搞一个FGO的脚本,但还是决定先从阴阳师开始入手
    毕竟现在版本官方已经有了自动御魂、觉醒和探索的脚本了。
    既然是这样那不如就搞一个抽卡的脚本好了,这样大佬(土豪,欧皇)们
    几百连抽就不用画符,和点SSR点到手软了XD。

    2. 实现

    参考了CSDN上两篇关于阴阳师探索和自动御灵的文章

    简单讲一下思路:
    通过图像识别(使用cv2这个库)来识别开始抽的蓝票、出现SSR(或SR)和十连抽结束这几个需要点按的场景。然后自动点按就可以了。

    不简单的讲一下具体实现
    (orz简书的markdown不支持流程图)

    1. 通过adb截图判断是否在抽卡界面
    2. 在的话,使用matchTemplate()函数识别开始召唤的按钮
    3. 点击,画符
    4. 同样使用matchTemplate()函数和模板对比识别SSR和SR并点击
    5. 若识别到“十连召唤”(即抽卡结束)点击返回
    开始抽卡的时候要识别的区域 出现SSR或SR要识别的区域 结束时要识别的区域

    这里主要通过adb来实现对手机的模拟点按和滑动(手机
    记得要开USB侦错啊QWQ)

    import os
    #模拟点按
    def tap(x0, y0):
        cmdTap = 'adb shell input tap {x1} {y1}'.format(
            x1=x0,
            y1=y0
        )
        print(cmdTap)
        os.system(cmdTap)
    #模拟滑动(用来画符的)
    def swipe(x0, y0, x1, y1, delay0):
        cmdSwipe = 'adb shell input swipe {x2} {y2} {x3} {y3} {delay1}'.format(
            x2=x0,
            y2=y0,
            x3=x1,
            y3=y1,
            delay1=delay0
        )
        print(cmdSwipe)
        os.system(cmdSwipe)
    #截图并返回图片
    def screenshot():
        os.system('adb shell screencap -p /sdcard/sh.png')
        os.system('adb pull /sdcard/sh.png .')
        return "sh.png"
    

    上面这个基本上是对手机的所有操作OWO。
    (我将这个单独保存在了项目目录的/lib/ats.py中,这样主程序就可以直接调用啦XD)
    然后来讲一下这里最核心的操作:图像识别orz

    #我们要用的其实就只有这一个库
    import cv2
    #不过我们还是要。。。
    import time
    import random
    import lib.ats #233 这个就是刚才那段代码
    import numpy as np
    

    好的我们先来个例子,就从识别开始抽卡的按钮开始。。。

    def start(sh):
        #一看就知道是导入图片orz
        imgSTART = cv2.imread(sh, 0)
        templateSTART = cv2.imread('res/START.png', 0) #我的模板保存在了项目目录的/res文件夹里
        #和模板对比
        resSTART = cv2.matchTemplate(imgSTART, templateSTART, cv2.TM_CCOEFF_NORMED)
        thresholdSTART = 0.85
        pos = []
        #如果result大于threshold才可以执行(不在界面你抽个啥)
        if (resSTART >= thresholdSTART).any():
            loc = np.where(resSTART >= thresholdSTART)
            for pt in zip(*loc[::-1]): #刚学Python没多久,我只知道这个压缩后切片QAQ
                pos.append(pt) #更新list
            return pos #返回按钮位置
        else:
            return 0
    

    然后是抽到SSR的时候(其实这个完全可以不写,因为SSR根本不存在(手动滑稽)XD)

    def ssr(sh):
        #这个不随机点说不定有封号的可能。。。
        xSSR = random.randrange(800, 1200)
        ySSR = random.randrange(400, 800)
        #导入图像和模板
        imgSSR = cv2.imread(sh, 0)
        templateSSR = cv2.imread('res/SR.png', 0)
        #和模板对比
        resSSR = cv2.matchTemplate(imgSSR, templateSSR, cv2.TM_CCOEFF_NORMED)
        thresholdSSR = 0.30 #这里啊QAQ可能是我的模板不是很好,大于0.3基本识别不出来
        #只要有SSR就行了,然后点一下
        if (resSSR >= thresholdSSR).any():
            lib.ats.tap(xSSR, ySSR)
    

    SR和这个代码其实是一样的,无非就是模板不同orz.
    但我的模板实在是太辣鸡了所以我把threshold设成了0.3(也就是说只要30%匹配就行了orz)所以。。。我的SSR和SR识别都混在了一起,也就是说无论出的是SR还是SSR都会按两次QAQ(R的话想必也是这样,只是用了图片测试。。。并没有票给我测试QAQ
    结束的识别和点击其实也和这个也差不多。。。

    好了基本上就只剩下主程序的代码了OWO
    主程序无非就是搞一个循环不断地截图,判断有没有出SR或SSR还有是不是已经抽完了而已

    def main():
        #里面的delay gap x1 y1 x2 y2 dly 都随机产生这里就懒得写了XD
        #这里是截图判断是否在抽卡界面
        sh = lib.ats.screenshot()
        pos = start(sh)
        if pos != 0:
            lib.ats.tap(pos[0][0], pos[0][1]) #从刚才的代码可以看到返回的是二维数组我们就选第一个好了
            lib.ats.swipe(x1, y1, x2, y2, dly)
            time.sleep(delay) #十连开始还有点动画的(感觉这个不加也行)
            while lib.ats.screenshot():  #不断的截图Zzz...
                gap = random.uniform(0.5, 1.5)
                time.sleep(gap)
                sh = lib.ats.screenshot()
                if end(sh) == 1: #抽卡没结束(匹配率低于threshold)返回1,否则返回0
                    ssr(sh)
                    sr(sh)
                elif end(sh) == 0: #结束的时候随机按一下
                    xEND = random.randrange(800, 1200)
                    yEND = random.randrange(400, 800)
                    lib.ats.tap(xEND, yEND)
                    print("Finished")
                    break
        else:
            print("Error") #如果不在抽卡界面的话。。。
    

    OWO基本上整个程序的吗都打上来了。。。
    整个完整的项目已经放到了Github上面,想看完整的就自己去看看咯QWQ

    3. 总结

    我觉得其实没什么好总结的orz
    其实感觉抽卡的脚本真的没什么用。。。


    好好学Python吧

    如果有Bug和更好的想法记得告诉我哦

    相关文章

      网友评论

          本文标题:用Python实现阴阳师自动抽卡

          本文链接:https://www.haomeiwen.com/subject/qliciftx.html