利用电脑玩Android版“天天连萌”刷高分(一)——截图
这几周微信游戏“天天连萌”由于第一名总是被一个同学所占据(没办法,我等级不够高游戏细胞又没他好),总在想怎么超越。正好小志同学(http://xiaozhi6156.iteye.com/)发给我一篇帖子,然后我找到原文(http://blog.csdn.net/longteng1116/article/details/12360269),向作者请教了部分问题(该文章下面还有我的大量评论呢),再琢磨了几天,终于自己也实现了这样的一个程序,利用电脑来玩“天天连萌”刷关卡和分数。
对这个程序的思路是这样子的:
1.从手机里截图到电脑。
2.解析这张图,并将其转换为二维数组。
3.循环搜索可以消除的方块对应的两个元素
4.将元素的位置转换为屏幕的坐标,然后对手机进行模拟按键
以上也将我们的焦点聚集在以下四个问题上:
1、如何截图
2、如何进行图像识别,转换为数组
3、连连看搜索算法
4、如何进行模拟按键
下面分别来看这四个问题。
[b]一、在PC端如何对Android手机截图[/b]
在电脑端进行Android截图的方法有多种。其中最快的应该是读取/dev/graphics/fb0,但是需要对手机先进行root。如果没有root的话,需要adb连接手机,然后执行adb shell进入android手机终端,将这个目录拷贝到sdcard,然后退出再执行adb pull,将该文件取出。
从网上得到的资料是,这个文件保存了5帧的framebuffer,只要读取出第一帧再进行处理就可以了。这个没试成功,而且这步骤略显麻烦,不适合在我的程序中应用。
上面是第一种方法。
第二种,使用adb shell screencap -p命令。
使用以上命令可以将手机截屏并输出屏幕,但是adb shell在传输时会将结果里的LF转换为CR+LF,所以还需要将结果改一下。如果是linux用户,可以这样做:
adb shell screencap -p | sed 's/\r$//' > screen.png
即将每一行末的回车符替换掉,再输出到screen.png。
如果是windows用户,可以先截图保存到sdcard,再使用adb pull命令将其取出。命令如下:
adb shell /system/bin/screencap -p /sdcard/tmp.pngadb pull /sdcard/screen.png d:/tmp.png
使用ImageIO类里的API可以读取这里的png图片为BufferedImage对象,当然也可以将BufferedImage对象保存为图片文件。
由于在程序里需要不停地截图,计算,所以这种方法同样不适合用在程序里。
第三种,使用android sdk里的AndroidDebugBridge。
需要引入ddmlib.jar包。然后通过调用AndroidDebugBridge.init(boolean)方法进行初始化,再调用AndroidDebugBridge.createBridge(str, boolean)创建一个AndroidDebugBridge对象,再使用AndroidDebugBridge对象的getDevices()获取所有连接的设备。该方法返回的是IDevice数组,调用IDevice对象的getScreenshot()方法就可以进行截图了。
下面附近我根据网友提供的相关代码整理之后的代码:
/* * @(#)ScreenShot.java Project:lianmeng * Date-Time:2013-10-11 下午1:08:36 * * Copyright (c) 2013 CFuture09, Institute of Software, * Guangdong Ocean University, Zhanjiang, GuangDong, China. * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package pw.msdx.lianmengassistant;
import java.awt.image.BufferedImage;import java.io.File;import java.io.IOException;
import javax.imageio.ImageIO;
import com.android.ddmlib.AndroidDebugBridge;import com.android.ddmlib.IDevice;import com.android.ddmlib.RawImage;
/** * copy from http://bbs.csdn.net/topics/390502035. modify by Geek_Soledad */public class AdbUtil { public static IDevice connect() { // init the lib // [try to] ensure ADB is running String adbLocation = System.getProperty("com.android.screenshot.bindir"); //$NON-NLS-1$ if (adbLocation != null && adbLocation.length() != 0) { adbLocation += File.separator + "adb"; //$NON-NLS-1$ } else { adbLocation = "adb"; //$NON-NLS-1$ }
AndroidDebugBridge.init(false /* debugger support */);
AndroidDebugBridge bridge = AndroidDebugBridge .createBridge(adbLocation, true /* forceNewBridge */);
// we can't just ask for the device list right away, as the internal // thread getting // them from ADB may not be done getting the first list. // Since we don't really want getDevices() to be blocking, we wait // here manually. int count = 0; while (bridge.hasInitialDeviceList() == false) { try { Thread.sleep(100); count++; } catch (InterruptedException e) { // pass }
// let's not wait > 10 sec. if (count > 100) { System.err.println("Timeout getting device list!"); return null; } }
// now get the devices IDevice[] devices = bridge.getDevices();
if (devices.length == 0) { System.out.println("No devices found!"); return null; }
return devices[0]; }
public static BufferedImage screenShot(IDevice device) { RawImage rawImage; try { rawImage = device.getScreenshot(); } catch (Exception ioe) { System.out.println("Unable to get frame buffer: " + ioe.getMessage()); return null; }
// device/adb not available? if (rawImage == null) return null;
// convert raw data to an Image BufferedImage image = new BufferedImage(rawImage.width, rawImage.height, BufferedImage.TYPE_INT_ARGB);
int index = 0; int IndexInc = rawImage.bpp >> 3; for (int y = 0; y < rawImage.height; y++) { for (int x = 0; x < rawImage.width; x++) { int value = rawImage.getARGB(index); index += IndexInc; image.setRGB(x, y, value); } } return image; }
/** * Grab an image from an ADB-connected device. */ public static boolean screenShotAndSave(IDevice device, String filepath) throws IOException { boolean result = ImageIO.write(screenShot(device), "png", new File(filepath)); if (result) { System.out.println("file is saved in:" + filepath); } return result; }
public static void terminate() { AndroidDebugBridge.terminate(); }}
最后说下第四种方法。这个是我在做模拟触摸的时候看到的,也是我目前采用的做法。我在做模拟触摸这一部分,用的是chimpchat.jar包里的api(为什么没用monkeyrunner.jar包里的api,具体原因后面会提到)。这里获取的是IChimpDevice对象,它也有截图的方法,即takeSnapshot()方法,返回的是IChimpImage对象,再调用IChimpImage对象的getBufferedImage()方法即可得到屏幕截图的BufferedImage对象。
代码如下:
private IChimpDevice mChimpDevice; private AdbBackend adbBack;
public Robot() { mImgHash = new ImageHash(); adbBack = new AdbBackend(); mChimpDevice = adbBack.waitForConnection(); }
/** * 截图 */ public BufferedImage snapshot() { IChimpImage img; // 这里用一个while循环是有时截图时会抛出超时异常,导致返回的是null对象。 do { img = mChimpDevice.takeSnapshot(); } while (img == null); return img.getBufferedImage(); }
使用这种方法,截取一张图在我手机上测试,大概是1200ms左右。读取/dev/graphics/fb0文件截图,据说一秒可以截5、6张,但如果通过java来调用的话,略显蛋疼,故不用。
需要注意的是,上面对我手机的截屏,图像是竖直的,而不是水平的。
接下来是将图片转换为2维数组,用到了一个图像识别算法,这些内容将在下一节续述。
利用电脑玩Android版“天天连萌”刷高分(一)——截图相关推荐
- 利用电脑玩android版天天连萌刷高分 二,利用计算机玩Android版“天天连萌”刷高分(一)——截图...
利用电脑玩Android版"天天连萌"刷高分(一)--截图 这几周微信游戏"天天连萌"由于第一名总是被一个同学所占据(没办法,我等级不够高游戏细胞又没他好),总 ...
- 利用电脑玩android版天天连萌刷高分 二,利用计算机玩Android版“天天连萌”刷高分(四)——模拟按键及程序优化...
利用电脑玩Android版"天天连萌"刷高分(四)--模拟按键及程序优化 这一系列文章,没想到从去年10月份以来,写了三篇我就忘了写了,现在才想起来,所以一不小心就成了跨年系列文章 ...
- 利用电脑玩android版天天连萌刷高分 二,天天连萌安卓刷分教程
天天连萌是腾讯最新推出的在线连连看游戏,小编给大家整理了天天连萌安卓经典模式和闪电模式的刷分教程.以及快速升级的方法,亲测可用.帮助大家轻轻松松获得250W. 天天连萌闪电模式250W修改教程 1.打 ...
- 利用电脑玩android版天天连萌刷高分 二,利用电脑玩Android版“天天连萌”刷高分(四)——模拟按键及程序优化...
这一系列文章,没想到从去年10月份以来,写了三篇我就忘了写了,现在才想起来,所以一不小心就成了跨年系列文章了. 第四篇主要是写一下如何进行模拟按键,以及对程序的一些优化以使到分数更容易达到更高的分. ...
- 利用电脑玩android版天天连萌刷高分 二,利用电脑玩Android版“天天连萌”刷高分(三)...
/** * 搜索,返回最优点. * * @return */ public Point search(int x, int y) { return LianlianKan.twoCornerSearc ...
- 计算机大学生必玩游戏,70%大学生用电脑玩游戏追剧,大一新生你还买电脑吗?家长们三思...
原标题:70%大学生用电脑玩游戏追剧,大一新生你还买电脑吗?家长们三思 八月到来,一张张录取通知飞向考生家庭,兴奋过后,数着开学日期,准大学生们开始准备大学用品.仔细想想,需要的东西还真不少:手机是必 ...
- android内存修改 跳一跳,Android版微信跳一跳小游戏利用技术手段达到高分的操作方法...
本文主要来讲个个好玩的东西,近来微信刚出的跳一跳微信小程序的游戏很火,看到很多人都达到了二三百分就各种刷朋友圈了. 甩手一个表情 最终我们达到的分数却是这样的: 羡慕吧 一定会有人拍手叫好," ...
- 原神ios android,原神苹果版如何用电脑玩 原神ios电脑版玩法教程
原标题:原神苹果版如何用电脑玩 原神ios电脑版玩法教程 现在有很多小伙伴都在玩原神手游,不过相对于传统的在手机上进行游戏,很多人都倾向于新玩法,就是在电脑上玩原神手游.下面小编就给亲们介绍下原神io ...
- 玩Android微信小程序版
最近开始针对项目性全面学习了一点js,和同事一起用MUI写了个项目,就敢拿出来献丑,我也是diaodiao的.经过几十个工时业余时间*(最近两周有点忙,周期拖得有点长,本来计划五一之前发出来的),在仿 ...
最新文章
- 【Android 逆向】Linux 文件分类 ( 普通文件 | 目录文件 | 链接文件 | 字符设备文件 | 管道文件 | 块设备文件 )
- python字符串与列表的相互转换
- 认证(登录)功能需求分析
- 创建数组表格PHP苹果价格,如何从PHP数组创建HTML表?
- 用RDLC报表(一)
- react 动态添加组件属性_React的组件动态参数使用Underscore和Context来传递
- Python 方法调用机制
- CompletableFuture异步任务的简单使用
- 用 Alan 和 Neovis.js 实现全新的 Doctor.ai
- 复制文件或文件夹时出错_为什么对于小白来说,复制文件一个都会出错???...
- xp系统打开itunes显示服务器失败,windowsxp系统安装不了itunes的两种解决方法
- 北京上空出现三个太阳?专家:冰晶云对太阳光散射形成“幻日”
- JavaScript async/await理解
- 用计算机上的图画画一幅画,计算机画图——初识画图程序
- 开通微信小店显示:系统繁忙,请稍后再试怎么回事?如何解决?
- 华为鸿蒙系统能玩安卓游戏吗_华为正式发布鸿蒙系统 鸿蒙和安卓游戏数据是否互通...
- 来说说wow魔兽地形
- 上下左右键的ASCII
- 【一起学Rust | 开源项目】效率提升工具espanso——在日常输入中使用代码提示
- 饮冰三年-人工智能-Python-33博客园山寨版之报障管理