平时不怎么玩游戏,有时消遣就玩玩QQ里的2D桌球,但是玩的次数少,不能像骨灰级玩家一样百发百中,肿么办呢?于是某天突发奇想,决定自己也来做个“外挂”。说是外挂,其实只是一个瞄准器,毕竟外挂是修改别人的软件,有点违法的意思,况且自己还没有能力去那么做,所以自己还是弄个瞄准器,做做弊,过下小瘾,同时也提高一下自己的编程能力。
2D桌球斯洛克的界面如下:
起初(也就是半年前),自己尝试做一个瞄准器的初始版本,用C#做,想法很简单:
Step1.把鼠标移到洞口,获取鼠标位置;
Step2.将鼠标放到要击打的球的圆心上,获取鼠标当前位置
Step3.根据进球时三点共线的原则按照球的半径自动将鼠标移动到准确的击球点。
示意图如下:
于是当初就按照这个想法做了,开始给自己做了个C#版,调用Windows API中的GetDesktopWindow,GetWindowDC,SetCursorPos三个函数,经过简单的数学运算,就基本实现了功能。代码如下:
使用时,只需要激活瞄准器窗口,按F1,F2获取鼠标位置,再根据洞口位置分别选按1、2、3、4数字键就行。
经过N次试验,成功率还挺高,只是有时候手动放置鼠标到被击打球圆心会出现误差,导致击球不准,当然,后来我赢了很多场比赛(嘿嘿,有点不道德!)。
再后来,又用C写了一遍,给同学用了。代码如下:
但是问题还存在,就是手动找圆心太麻烦,一般用触摸板比鼠标方便,但是仍然很不智能,于是一直想着用图像处理的方法去自动找圆心。
这几天在做数模,经常用到Matlab,刚做了一道要处理图像的题,正好想起这个问题来,于是,搁置的瞄准器继续开始完善了。
很快就有了思路,通过C#截图,然后Matlab进行图像滤波,灰度化,二值化以及边缘提取,然后进行圆曲线拟合,最后找到圆心,返回到C#中使用,代替手动找点。
首先,我用Matlab写了个函数:
然后用Matlab2010b里的deploytool导出.net能使用的程序集dll文件(不知道为什么malab2009b在build时出现.net framework相关的错误),通过C#添加引用,调用其返回的参数,成功完成自动拾取圆心。
改进后代码如下:
经试验,成功率也很高,偶尔出现不准(估计是边缘提取和计算精度的问题),但是大多数偏差可以手动修正。
到此为止,改进版全部完成。希望以后继续改进,更加智能化。