阴阳师肝不动了,试试Python吧

引子 啰嗦的部分,可以跳过

前几日入了阴阳师的坑,经过了前期的快速升级后,发现这个游戏真的是要肝啊。每天都是身体被掏空了。不知道大家有没有感觉,就是这个游戏吧,也不需要集中什么注意力,但是隔一会儿就要操作一下,没法集中精力干别的事情。阴阳师的操作也比较单一,于是去找找看有没有大神写好的脚本。果然人民群众想到我的前面去了,于是下了安卓虚拟机,上脚本,谁用谁知道,救了我的肝呀。奈何我的账号在苹果上,于是越狱下载,又是一顿折腾。终于在pad上也可以运行了。

但是,我很好奇这些脚本是怎么写的,发现了按键精灵。这里建议大家去官网上下载。因为,连官网下的都有一堆乱七八糟的软件啊!其他网站我就更不敢保证了。学了一会儿发现,这个软件确实很好用,很多操作都简化了,挺适合学习和理解编程的。但是导出文件的时候发现要加密导出的话还要注册会员,不然只能导出源文件......反正给我的感觉好用,但是不爽,算了,还是用python吧。

Python选定了之后,各种找资料,下库文件,心累。我还用的是python3,心都快碎了。说点感想,搜索资料的时候,最怕的就是作者以为我什么都懂,只是简单提了一句如何如何,可是臣妾真的不懂啊!所以,我尽力把过程写的详细些,让大家少走些弯路。虽然这个程序只写了两天,但是现在有些东西可能也忘了,如果有什么没说清楚的地方可以私信我。

正文 本文只是学术探讨,学术交流,交流.......网易爸爸不要找我

思路 1.模仿按键精灵的功能,抓取需要点击的位置的坐标,将鼠标移动过去后点击。可以解决妖气封印、御魂、石巨等只需要点击的功能。

2妖怪探索,需要将屏幕截图,然后通过一个图像识别(异常的简单,哈哈,我都佩服自己的机智),点击下面图标,进入交战界面。

image

程序实现 1先说实现鼠标点击的功能。

安装pyautogui这个库,注意自己的python版本(2.x还是3.x)和操作系统的位数(32/64位)。还会出现安装失败之类的各种问题,反正是一阵折腾。

使用pyautogui.moveTo()这个方法,把鼠标移动到制定的位置,比如将鼠标移动到屏幕的左上角就是pyautogui.moveTo(0,0)。pyautogui.click()实现单机左键。

把需要点击的位置在显示器上的位置都找好,我用的显示器是19201080的,所以以下代码只能运行在19201080的显示器上,且是最大化模拟器的窗口时各种需要点击地方的坐标,运行在其他平台的话需要相应的改变坐标。以下是实现妖气封印自动点击的代码。前提是登陆进去后人物不要移动,只在初始位置,点开下面的卷轴,如下图这样。然后运行程序,因为人物走动到其他位置后按钮的坐标就变化了。

image

import pyautogui
import time
#妖气封印函数
def yaoqi():
    #点击组队
    pyautogui.moveTo(424,904)
    pyautogui.click()
    time.sleep(2)
    #点击妖气封印
    pyautogui.moveTo(433,852)
    pyautogui.click()
    time.sleep(2)
    start=time.clock()
    while(True):
        end=time.clock()
        #刷新、加入,准备
        pyautogui.moveTo(1116,907)
        pyautogui.click()
        time.sleep(0.1)
        pyautogui.moveTo(1538,330)
        pyautogui.click()
        pyautogui.moveTo(1668,806)
        pyautogui.click()
        #判断运行时长
        if int(end-start)==600:
            break
#天雷鼓函数

def Tianlei():
    #点击组队
    pyautogui.moveTo(424,904)
    pyautogui.click()
    time.sleep(2)
    #点击天雷鼓
    pyautogui.moveTo(466,639)
    pyautogui.click()
    time.sleep(2)
    start=time.clock()
    while(True):
        end=time.clock()
        #刷新、加入,准备
        pyautogui.moveTo(1116,907)
        pyautogui.click()
        time.sleep(0.1)
        pyautogui.moveTo(1538,330)
        pyautogui.click()
        pyautogui.moveTo(1668,806)
        pyautogui.click()
        #判断运行时长
        if int(end-start)==600:
            break

if __name__ == '__main__':
    yaoqi()

上面写了妖气封印和天雷鼓的函数,运行的是妖气封印的函数。需要注意的是,打完妖气封印后直接就退回到了主界面,也就是上图这个界面,还需要重新打开卷轴点击组队,然后运行。理想情况应该是继续打开卷轴开始新一轮的刷新。也蛮简单的,这里我们只做学术交流,点到为止,哈哈~

2妖怪发现部分,也就是探索部分。和前一步类似,通过和前面一样的确定坐标,我们一路点击进入了这个界面。

image

这里的难点在于点击怪物头上的交战符号进入交战。起初我是在这个交战符号附近的Y坐标的高度一路点过去若干个点,总能点到,如下图的红点。然后适当的延迟几秒后,等切换到下一个交战的界面后还是点点的老问题。

image

但是这样有一个问题,我不知道这页的妖怪什么时候打完了,为了保险,可以多循环几次。为了保险,设置循环六次,但是经常会出现这页只有一个妖怪,打完了之后,傻傻的等到循环结束后才走到下一个页面。 其实一开始我就想到了图像识别这个方法。在按键精灵中也有这个功能,在一张大图上面找出来指定的图案位置,然后将鼠标移动过去。然后我就找python中图像匹配的库,理论上只要在上图中找到下面这个图片,然后把鼠标移动过去,就能实现精准的点击了。

重点来了,我在网上找到的方案很多都是同尺寸图片进行比较,然后得出相似度,我这种需求的基本找不到答案。一番思考之后,我想出了下面这个方案:

把大图切成若干个小图,这样尺寸的问题就解决了。然后每个小图和进行比较,选出相似度较大的方块,然后把鼠标移动到这个方块中点击。 但是这个方案我做到一半的时候发现,这个图像比较好像......比较....慢啊,之前我就担心这样的问题。在查找资料的时候就看到各种比较算法什么的,给我的感觉就是事情没有这么简单,什么神经学习,人工智能之类的,我只是写一个脚本啊,要不要这样。

于是乎我想到下面这个出奇简单的方法,速度奇快,勉强也能叫图像识别吧,哈哈!

如上图,这次我们只采集红点处的颜色信息,然后与目标颜色比较,途中交战图标的棕色的rgb颜色是(53,30,15),由于是个渐变色,我们只要设定一个大致的范围,比如R(50-70)G(30-40)B(10-30)这个区间,满足这个区间的采样点我们用鼠标去点击。适当的调整采样的间隔和颜色的偏差区间,可以得到满足准确点击的效果,同时也满足了对处理时间的要求。 下面是代码部分。有进入对战后点击准备和结束对战后点击奖励退出的部分,以及本页怪物打完后走到下一页的部分。很简单,没有什么难度。同时在找怪物时统计了本页怪物数量,打完后走到下一页,就不会傻傻呆着了,这一部分还没有认真测试,还能写的更好点。

from PIL import ImageGrab
from PIL import Image,ImageChops
import pyautogui
import time
#寻找怪物函数
def find():
    k=0
    #截图到交战图片
    im=ImageGrab.grab((0,300,1920,600))
    pix=im.load()
    #网格取点,点击交战图标
    for i in range(0,1920,30):
        for j in range(0,300,30):
            r,g,b=pix[i,j]
            if 50<r<70 and 30<g<40 and 10<b<30:
                pyautogui.moveTo(i,j+300)
                pyautogui.click()
                k=k+1
    return(k)
def Fight():
    #对战部分
    time.sleep(8)
    pyautogui.moveTo(1668,806)
    pyautogui.click()
    #循环点击退出对战界面
    for n in range(0,15):
        pyautogui.moveTo(936,554)
        pyautogui.click()
        time.sleep(4)
def walkleft():
    pyautogui.moveTo(137,695)
    pyautogui.click()
    time.sleep(3)
def walkright():
    pyautogui.moveTo(1805,752)
    pyautogui.click()
    time.sleep(3)

if __name__ == '__main__':
    num=1
    while(num):
        #num统计出页面的怪物个数,确定循环次数
        num=find()
        Fight()
    #右走两次
    walkright()
    walkright()
    num=1
    while(num):
        num=find()
        Fight()
    walkright()
    walkright()
    num=1
    while(num):
        num=find()
        Fight()
    walkleft()
    walkleft()
    num=1
    while(num):
        num=find()
        Fight()