最近在玩某款很火热的手游,但手游中某些设计实在过于枯燥,于是生出了写一个辅助工具的想法,下面开始具体阐述
在此注明,作者技术很渣,所以此文中不会出现什么算法等等,一切以务实、实现功能为主,优化问题我们可以后续考虑,不过从现在来看...效率还可以
一.预研阶段
在此简述一下这款游戏,进副本,刷怪升级。怪物有3中,经验怪、金币怪、装备怪,我们为了练级,只打经验怪物
1. 明确操作流程
简而言之,如果我们想让程序帮我们做什么,我们需要明确的告诉他,你应该怎么做,做了之后可能会出现什么情况,每种情况你该怎么处理
在此简单列一下
------ 阶段1 ----
-- 进入副本
------ 阶段2 ----
-- 识别经验怪物 -- 若没有则退出副本
-- 攻击该怪物
------ 阶段3 ---
-- 点击准备
-- 等待游戏结束 (在此感谢这款手游提供了自动战斗的AI,所以我们只需要点击战斗, 就可以了, 另,刷怪肯定要挑软柿子,所以我们需要保证可以战斗胜利)
-- 进入阶段2
2. 脚本的运行方式
手游可以在模拟器上跑,也可以在实体机上跑,所以我们的脚本可以有两种运行平台,PC / Android
下面简单分析下两种利弊
1. PC
或者说,PC运行模拟器,我们用java/其他程序去调用windowsapi,操作鼠标之类的
优点: 模拟器运行稳定,不会出现卡死(原谅我的手机玩游戏的过程中..可能会出现的各种情况,尤其是..长时间运行)
调用API简单
可以多开(虽然对我而言意义不大,因为我只玩一个号..将来或许考虑玩个小号什么的)
缺点: PC运行的过程中,不能。。干别的,当然看电影什么的,还是可以的
另: 开个虚拟机干这种事也可以,但是对windows研究的不深,所以不作考虑
2.Android
优点: 不用占用电脑
缺点: 唔,缺点好多
防封,在手机上用程序来模仿用户操作较难(天知道游戏APK会不会有各种方式监听到你是否是人为操作, 这部分后面再说)
稳定性, 谁也不能保证你的程序在后台运行就可以永远存活(作者是Android源码开发的...用工程机倒是可以保证这一点,但是...太费劲了不是,而且没有性能特别好的机器让我作死的带回家玩)
不能多开。
3. 封号规避
虽然本人没有在游戏公司工作过,但个人认为,游戏公司认为你是脚本操作的关键点在以下几点
1. 用户重复活动
具体来说就是,你一个人在那刷了7天7夜的一只怪,不眠不休,从不停歇,你说你是正常人,宝宝不相信..
2. 监听系统事件
由于我们选择PC上运行,首先游戏是运行于模拟器上的,然后我们在windows平台上调用API去点击模拟器内部的按钮,游戏是绝对检测不到的,所以这点略过
3. 用户操作
比如说有个按钮是50x50的,你一个人操作那么多次,每次都点击到25,25上这个坐标,你是用针在玩吗?这么精准?
暂且就总结这些,核心就是,莫方人为操作。
二. 需求分析
在此把上面的阶段搬下来
------ 阶段1 ----
-- 进入副本
------ 阶段2 ----
-- 识别经验怪物 -- 若没有则退出副本
-- 攻击该怪物
------ 阶段3 ---
-- 点击准备
-- 等待游戏结束 (在此感谢这款手游提供了自动战斗的AI,所以我们只需要点击战斗, 就可以了, 另,刷怪肯定要挑软柿子,所以我们需要保证可以战斗胜利)
-- 进入阶段2
阶段1-- 没什么好说的,点击某个按钮
阶段2-- 这个量较大,稍后详谈
阶段3-- 核心技术跟阶段2相似
二. 核心部分
其实这个脚本的核心难点就在于识别,我在这的设计是,截取游戏图片,用尽可能快速的方式确定当前图片中是否有我们想要的(经验怪图标、战斗胜利图标)
第一步,截图这一步就不说了,网上API多得是,不过在此要注明一点,模拟器分辨率最好笑点,反正程序也不是肉眼识别,你确定像素级别可以分辨出这些东西就可以了,我的模拟器最小只能设置成600*480.
另:截图不需要全截,你要知道,你截的图片每大1像素,你的程序处理的就会慢一点,所以..我们只截游戏的一部分,比如..只有这部分可能出现经验怪物的图标,只有这部分可能出现胜利的标志之类的
第二步,识别
所以在这里,我们需要把要识别的东西先..提取出来,比如经验图标,比如胜利标志
但是,计算机每次显示这些图标的时候,不可能完全的一模一样,不过..我们不在乎,我们只需要一个大概的就可以了,大小相同,形状相同,至于说颜色有多多少少的明暗变化,问题不大
目的:我们需要从截取的图片B中,查询到图标A的位置
实现方案:
获取图片B中的ARGB值,获取图标A的ARGB值,然后比对
具体实现方式:
预先读取图标A的0,0这个点的RGB值
for循环,从第一行开始遍历图片B的每一个像素点的RGB值,与A 0,0的RGB值比较
若相似:
假设图标A的宽度是50, 假设图片B上的1,2 点与图片A的初始点相似,则比较 图标B上的 1,51,与图标A中0,50点的RGB值,
若再相似,则继续比较,总的来说,就是以矩形框的方式,比较图片B和图标A
若不相似:
则...继续比较下一个点
在此说明,如果你直接RGB的值进行==比较,绝对拿不到任何结果,所以我在此用的是 Ra 的值是否在 Rb+20 - Rb-20这个区间内, 20这个值越大,比较结果越多
第三步,既然可以识别到具体的点了,则剩下的工作就跟具体的业务逻辑挂钩了
三,当然..其实这游戏经验怪物的图标跟攻击图标并非在同一点,不过..作者好懒,不继续讲了,想想办法其实还是蛮简单的,写的过程中还有一些其他的,比如..怎么识别文字,怎么识别不同背景上的固定文字,判定到某种事件时怎么通知自己(这里我用的email...有升级了就给自己发个email- -,提醒自己来换上场的..角色)
之类的还有很多吧,具体这些..写起来好麻烦,所以先不写了,哪天有心情再继续分享-。- 原谅我的懒
此文有诸多不足,有什么不对的地方还请大家多多指点,若觉得实在太low,还请一笑而过,毕竟,只是闲暇时写的小demo,认真你就输了