Mac大家来找碴豪华版辅助工具
最近想学一下Mac系统的程序编写,觉得从辅助工具开始写起比较有兴趣学下去。
在App Store的免费游戏分类里有一个《大家来找碴豪华版》的游戏,因为几年前写过《QQ美女找茬》游戏的辅助,所以就决定写一个找碴的辅助工具了。
《QQ美女找茬》左右两幅图都是未修改过的原图,然后游戏把5个修改过的小图片绘制在右边的图片上面,这样就形成了5处不同的地方。
通过判断左右两幅图相同位置的点的颜色值是否相同,就可以知道该点是不是修改过的。如果把不同的点都替换为黄色的话,可以看到有5个很规则的小方块:
但是《大家来找碴豪华版》这个游戏比较复杂,首先图片5处不同的地方都是直接ps的,所以不会形成很规则的方块。
还有右边的图片经过一定的处理,左右两幅图相同位置的点的颜色值有所偏差,所以不能通过判断两个点的颜色值是否相等来区分,而是通过计算颜色的RBG值的方差是否大于某个值来区分。
下面是用到的一些代码:
一、遍历所有打开的窗口,通过游戏窗口名获取窗口id。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| - (id)initWithWindowName:(NSString *)windowName { if (self = [super init]) { self.windowName = windowName; self.windowId = [self windowId]; } return self; }
- (CGWindowID)windowId { CFArrayRef windowsRef = CGWindowListCreate(kCGWindowListOptionOnScreenOnly, kCGNullWindowID); NSArray *windowInfos = (__bridge NSArray *)CGWindowListCreateDescriptionFromArray(windowsRef); NSUInteger count = windowInfos.count; for (NSInteger 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; }
|
二、截取该窗口的图像。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| - (void)captrueWindow { 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值的方差。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| CGFloat avgRed = (red1 + red2) / 2; CGFloat avgGreen = (green1 + green2) / 2; CGFloat avgBlue = (blue1 + blue2) / 2; CGFloat sRed = pow(red1 - avgRed, 2); CGFloat sGreen = pow(green1 - avgGreen, 2); CGFloat sBlue = pow(blue1 - avgBlue, 2); CGFloat 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可以得出区域的横坐标中点,同理得出区域的纵坐标中点。
再让鼠标移动到这个中点的坐标点击就行了。
不知道是不是录像的原因,视频里辅助的窗口显示的颜色有问题,而实际看到是没问题的。
视频观看地址为:
https://v.youku.com/v_show/id_XNTk3NTY3NTU2.html