这几周微信游戏“天天连萌”由于第一名总是被一个同学所占据(没办法,我等级不够高游戏细胞又没他好),总在想怎么超越。正好小志同学(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版“天天连萌”刷高分(一)——截图相关推荐

  1. 利用电脑玩android版天天连萌刷高分 二,利用计算机玩Android版“天天连萌”刷高分(一)——截图...

    利用电脑玩Android版"天天连萌"刷高分(一)--截图 这几周微信游戏"天天连萌"由于第一名总是被一个同学所占据(没办法,我等级不够高游戏细胞又没他好),总 ...

  2. 利用电脑玩android版天天连萌刷高分 二,利用计算机玩Android版“天天连萌”刷高分(四)——模拟按键及程序优化...

    利用电脑玩Android版"天天连萌"刷高分(四)--模拟按键及程序优化 这一系列文章,没想到从去年10月份以来,写了三篇我就忘了写了,现在才想起来,所以一不小心就成了跨年系列文章 ...

  3. 利用电脑玩android版天天连萌刷高分 二,天天连萌安卓刷分教程

    天天连萌是腾讯最新推出的在线连连看游戏,小编给大家整理了天天连萌安卓经典模式和闪电模式的刷分教程.以及快速升级的方法,亲测可用.帮助大家轻轻松松获得250W. 天天连萌闪电模式250W修改教程 1.打 ...

  4. 利用电脑玩android版天天连萌刷高分 二,利用电脑玩Android版“天天连萌”刷高分(四)——模拟按键及程序优化...

    这一系列文章,没想到从去年10月份以来,写了三篇我就忘了写了,现在才想起来,所以一不小心就成了跨年系列文章了. 第四篇主要是写一下如何进行模拟按键,以及对程序的一些优化以使到分数更容易达到更高的分. ...

  5. 利用电脑玩android版天天连萌刷高分 二,利用电脑玩Android版“天天连萌”刷高分(三)...

    /** * 搜索,返回最优点. * * @return */ public Point search(int x, int y) { return LianlianKan.twoCornerSearc ...

  6. 计算机大学生必玩游戏,70%大学生用电脑玩游戏追剧,大一新生你还买电脑吗?家长们三思...

    原标题:70%大学生用电脑玩游戏追剧,大一新生你还买电脑吗?家长们三思 八月到来,一张张录取通知飞向考生家庭,兴奋过后,数着开学日期,准大学生们开始准备大学用品.仔细想想,需要的东西还真不少:手机是必 ...

  7. android内存修改 跳一跳,Android版微信跳一跳小游戏利用技术手段达到高分的操作方法...

    本文主要来讲个个好玩的东西,近来微信刚出的跳一跳微信小程序的游戏很火,看到很多人都达到了二三百分就各种刷朋友圈了. 甩手一个表情 最终我们达到的分数却是这样的: 羡慕吧 一定会有人拍手叫好," ...

  8. 原神ios android,原神苹果版如何用电脑玩 原神ios电脑版玩法教程

    原标题:原神苹果版如何用电脑玩 原神ios电脑版玩法教程 现在有很多小伙伴都在玩原神手游,不过相对于传统的在手机上进行游戏,很多人都倾向于新玩法,就是在电脑上玩原神手游.下面小编就给亲们介绍下原神io ...

  9. 玩Android微信小程序版

    最近开始针对项目性全面学习了一点js,和同事一起用MUI写了个项目,就敢拿出来献丑,我也是diaodiao的.经过几十个工时业余时间*(最近两周有点忙,周期拖得有点长,本来计划五一之前发出来的),在仿 ...

最新文章

  1. 【Android 逆向】Linux 文件分类 ( 普通文件 | 目录文件 | 链接文件 | 字符设备文件 | 管道文件 | 块设备文件 )
  2. python字符串与列表的相互转换
  3. 认证(登录)功能需求分析
  4. 创建数组表格PHP苹果价格,如何从PHP数组创建HTML表?
  5. 用RDLC报表(一)
  6. react 动态添加组件属性_React的组件动态参数使用Underscore和Context来传递
  7. Python 方法调用机制
  8. CompletableFuture异步任务的简单使用
  9. 用 Alan 和 Neovis.js 实现全新的 Doctor.ai
  10. 复制文件或文件夹时出错_为什么对于小白来说,复制文件一个都会出错???...
  11. xp系统打开itunes显示服务器失败,windowsxp系统安装不了itunes的两种解决方法
  12. 北京上空出现三个太阳?专家:冰晶云对太阳光散射形成“幻日”
  13. JavaScript async/await理解
  14. 用计算机上的图画画一幅画,计算机画图——初识画图程序
  15. 开通微信小店显示:系统繁忙,请稍后再试怎么回事?如何解决?
  16. 华为鸿蒙系统能玩安卓游戏吗_华为正式发布鸿蒙系统 鸿蒙和安卓游戏数据是否互通...
  17. 来说说wow魔兽地形
  18. 上下左右键的ASCII
  19. 【一起学Rust | 开源项目】效率提升工具espanso——在日常输入中使用代码提示
  20. 饮冰三年-人工智能-Python-33博客园山寨版之报障管理

热门文章

  1. Find My资讯|新系统苹果Find My不再显示AirTag电池电量
  2. 如何用AI制作金属渐变
  3. background 部分用法 背景颜色渐变
  4. python 录音本地转文字_用Python将抖音视频转换为字符视频
  5. Linux系统编程08---守护进程与线程
  6. JAVA实验6继承与接口,java实验6继承与接口
  7. 任务三 类的继承与派生
  8. 高颜值充电宝推荐,颜值高质量好的充电宝盘点
  9. 抄袭--高尔夫球(黄?高雅?)
  10. android不支持USB怎么办,安卓手机通过USB连接不上电脑怎么办