Mac大家来找碴豪华版辅助工具

时间:2013-08-27 | 分类:个人日志,学习园地 | 浏览:4825 | 评论:3 | 发表评论

最近想学一下Mac系统的程序编写,觉得从辅助工具开始写起比较有兴趣学下去。

在App Store的免费游戏分类里有一个《大家来找碴豪华版》的游戏,因为几年前写过《QQ美女找茬》游戏的辅助,所以就决定写一个找碴的辅助工具了。

《QQ美女找茬》左右两幅图都是未修改过的原图,然后游戏把5个修改过的小图片绘制在右边的图片上面,这样就形成了5处不同的地方。

通过判断左右两幅图相同位置的点的颜色值是否相同,就可以知道该点是不是修改过的。如果把不同的点都替换为黄色的话,可以看到有5个很规则的小方块:

但是《大家来找碴豪华版》这个游戏比较复杂,首先图片5处不同的地方都是直接ps的,所以不会形成很规则的方块。
还有右边的图片经过一定的处理,左右两幅图相同位置的点的颜色值有所偏差,所以不能通过判断两个点的颜色值是否相等来区分,而是通过计算颜色的RBG值的方差是否大于某个值来区分。

一、遍历所有打开的窗口,通过游戏窗口名获取窗口id。

//初始化
- (id)initWithWindowName:(NSString *)windowName
{
    if (self = [super init]) {
        self.windowName = windowName;
        self.windowId = [self windowId];
    }
    return self;
}

//通过窗口名字获取窗口id
- (CGWindowID)windowId
{
    //获取屏幕上所有窗口的信息
    CFArrayRef windowsRef = CGWindowListCreate(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
    NSArray *windowInfos = (__bridge NSArray *)CGWindowListCreateDescriptionFromArray(windowsRef);
    NSUInteger count = windowInfos.count;
    
    //遍历窗口,找到名字相同的窗口,获取窗口id
    for (int i = 0; i < count; i++) {
        NSDictionary *windowInfo = windowInfos[i];
        NSString *name = [windowInfo objectForKey:(NSString *)kCGWindowName];
        if ([name isEqualToString:self.windowName]) {
            return (CGWindowID)CFArrayGetValueAtIndex(windowsRef, i);
        }
    }
    return 0;
}

二、截取该窗口的图像。

- (void)captrueWindow
{
    //通过窗口id获取窗口信息
    CFArrayRef windowRef = CGWindowListCreate(kCGWindowListOptionIncludingWindow, self.windowId);
    NSArray *windowInfos = (__bridge NSArray *)(CGWindowListCreateDescriptionFromArray(windowRef));
    NSDictionary *windowInfo = windowInfos[0];
    
    //获取窗口坐标和大小
    NSDictionary *bounds = [windowInfo objectForKey:(NSString *)kCGWindowBounds];
    CGRectMakeWithDictionaryRepresentation((__bridge CFDictionaryRef)(bounds), &_imageRect);
    
    //通过和大小创建图像
    CGImageRef imgRef = CGWindowListCreateImageFromArray(_imageRect, windowRef, kCGWindowImageDefault);
    NSImage *image = [[NSImage alloc] initWithCGImage:imgRef size:NSZeroSize];
    [image lockFocus];
    self.bitmap = [[NSBitmapImageRep alloc] initWithFocusedViewRect:NSMakeRect(0, 0, image.size.width, image.size.height)];
    [image unlockFocus];
}

三、求两点颜色RGB值的方差。

float avgRed   = (red1   + red2)   / 2;
float avgGreen = (green1 + green2) / 2;
float avgBlue  = (blue1  + blue2)  / 2;
float sRed   = pow(red1   - avgRed,   2);
float sGreen = pow(green1 - avgGreen, 2);
float sBlue  = pow(blue1  - avgBlue,  2);
float s2 = sRed + sGreen + sBlue;

if (s2 > 200) {
    //如果该点不同,则替换为红色
    [self.leftBitmap setColor:[NSColor redColor] atX:i y:j];
} else {
    //否则降低该点红色的色值
    NSColor *color = [NSColor colorWithCalibratedRed:red1*0.1 green:green1 blue:blue1 alpha:1];
    [self.leftBitmap setColor:color atX:i y:j];
}

如果方差大于某个值(例如200),就说明两点的颜色不相近,则把该点的颜色替换为红色。否则就把该点的R值除以10以降低红色值,这样就不会干扰到红点了。结果如下:

四、自动点击。
要实现自动点击,就要找出5个红点连起来的区域。
我的做法是把图片分割成20*20=400个方块,创建一个400个元素的数组,统计每个方块里红点的数量存到数组里,然后按从多到少排序。
排序后数组的第一个元素就是有最多红点的,然后以这个格子所在的位置开始上下左右递归。如果相邻的格子里有红点,就说明它们是连在一起的区域,把它们存到一个临时数组,并把他们从大数组里移除。
递归结束后把临时数组里的元素的x坐标和y坐标分别进行排序,然后把最小的x值和最大的x值相加再除以2可以得出区域的横坐标中点,同理得出区域的纵坐标中点。
再让鼠标移动到这个中点的坐标点击就行了。

不知道是不是录像的原因,视频里辅助的窗口显示的颜色有问题,而实际看到是没问题的。

标签: , , ,
本文链接: Mac大家来找碴豪华版辅助工具
版权所有: 破博客, 转载请注明本文出处。

3个评论

  1. anthony
    2013/09/01 10:46:06

    :evil: 大家来找茬~

发表评论

您的昵称: *

您的邮箱: * (显示gravatar头像)

联系方式: