前段时间老同学叫我做个连连看外挂,但是那时候要考试没时间做,就耽搁下来了,直到最近几天才又萌生了写连连看外挂的念头,刚好是周末,正好有时间来写这个外挂。
写外挂之前,先理顺写外挂的思路,第一步当然是先玩几盘连连看,熟悉一下游戏规则,这叫“实战出真知”“实践是检验真理的唯一标准”。几盘下来,眼睛都花了,愣是没赢过一盘,看来我不是玩连连看的料……虽然游戏没赢,但是我从游戏的过程中知道了游戏的规则,后来再看看游戏的规则介绍,和我理解的差不多:两个图案直接可以用线段链接,且线段数小于三。至此,游戏了解完毕。
接下来,在实现游戏算法前必须做的就是要把游戏区域编码,把复杂的图像信息转化为容易处理的矩阵,这样才可以和后面的算法进行对接。
先看看游戏图像和相应的编码矩阵:
(15)
(13)
要把游戏区域进行编码,那必须先把游戏区域定位,然后再定位游戏区域的各个图像的位置,接着再对各个图像进行标识,把相同的图像归类和统计。在这一部分,我用了上次做的“大家来找茬外挂”的基础,先截屏,确定好游戏区域,然后把游戏区域截取下来。这部分内容可以参照我上两篇找茬外挂的教程,这里就不赘述了。
在游戏区域图像获得后,就可以开始游戏图像的编码了,通过观察可以看出来每个图像块是以31*35的大小重复的,整个游戏区域共有19*11个图像块,于是先声明一个board[11][19]的二维数组进行存储各个图像的ID,至于图像的比较,我是用每个图像的15个像素进行比较的,如果rgb分别相同,这这两个图像必为同一图像。网上有童鞋说用5个像素甚至4个像素就可以确定两幅图像是否相同,但是我试过会有出现误判,所以我建议还是多取几个点好,反正这对于计算机来说真的不算什么,影响不了速度的,至少肉眼还看不出来。
从头开始比较各个图像块,把相同的图像只放一个进链表,并且写入改图像块的ID。当比较完毕,我们就可以得到30多个都不一样的图像块链表,这个链表就是这个游戏区域的所有图像块的索引。下面是我定义的这个索引图像块的结构体,大家制作的时候可以作为参考,其中我还增加了一项count来统计每个图像块的数量,后来才发现出来道具图像块是两个,其他的图像块都是4个,等等,我还发现了背景图像块也统计出来了,是80几个,当然不同的游戏场景的背景图像块的数量不一样,但是通过游戏可以知道,背景图像块必定是大于4个的,所以,我用图像块的数来来进行判断该图像是否是背景图像块。判断背景图像块有什么用?呵呵,这作用就大了,只有知道了图像块的ID,在后面的才好实现算法进行通路的检测(在前面的图像编码图片就可以看出来,背景图像块的ID为13)。
typedef struct{
IplImage* img;
int id;
int count;
}diffImg;
//Begin将所有不同的图案推入链表
for(int j=0;j<11;j++)
for(int i=0;i<19;i++){
rect.x=31*i;
rect.y=35*j;
rect.width=31;
rect.height=35;
cvSetImageROI( pImg,rect );
cvCopy(pImg,temp1);
bool haveSame=false;
std::list<diffImg>::iterator it = NULL;
if (listImg.empty())
{
diffImg dif;
dif.img=temp1;
dif.id=id;
listImg.push_back(dif);
temp1 =cvCreateImage(cvSize(31, 35), pImg->depth,pImg->nChannels);
cvCopy(pImg,temp1);
}
for(it= listImg.begin(); it!=listImg.end(); ++it)
{
IplImage *temp3=it->img;
if(isSame(temp1,temp3))
{
haveSame=true;
board[j][i]=it->id;
}
}
if(!haveSame)
{
temp2 =cvCreateImage(cvSize(31, 35), pImg->depth,pImg->nChannels);
cvCopy(temp1,temp2);
diffImg dif2;
dif2.img=temp2;
id+=1;
dif2.id=id;
board[j][i]=id;
listImg.push_back(dif2);
}
}//End将所有不同的图案推入链表
以上面的方法得到背景图像块的ID后就可根据该ID把所以背景图像圈出来,下面看看效果图:
(11)
圈出相同ID的图像块:
(10)
编写核心算法,主要就是对两个图像块进行通路的判断。这部分算法可以上网找找参考资料,研究连连看算法的人还挺多的,这里我也就不赘述了。
把第一不获取到的图像编码和算法进行对接,然后再输出结果,最后把输出的结果转化会模拟鼠标点击,这个外挂就算是做好了。这部分内容在以前的外挂详细说明过。
到这里,外挂做好了,进入测试发现无敌了,玩了到今天已经7000多分了……
后来发给同学测试,同学测试后反馈说速度太快太假了,他建议加个功能可以调节点击快慢。这个建议不错,于是我加入一个编辑框,随时可以改变点击的间隔时间,哈哈,设置一个合理的间隔时间别人就不会怀疑我是用外挂了。
看看最终界面:
(11)
然后再看看设置间隔时间为10毫秒的测试效果(个人感觉挺壮观的):
(11)
其他的两篇外挂文章:
http://blog.long1986.com/blog/20100311173/based-on-opencv-and-mfc-of-everyone-to-finding-fault-plug-in-upgrade.html (32)
http://blog.long1986.com/blog/20100311168/using-vc-opencv-to-write-everyone-to-finding-fault-plug-in.html (32)
题目为:用VC++, OpenCV写大家来找茬外挂
如无特殊说明,本站内容均为原创,转载请注明: 转载自longlongago (29)
本文链接地址: http://blog.long1986.com/blog/20100328206/lianliankan-plug-in-production-based-on-opencv-vc.html (21)