扫雷外挂的设计与实现(三)

真烟假烟真真假

真烟假烟真真假

2016-02-19 19:31

关注图老师设计创意栏目可以让大家能更好的了解电脑,知道有关于电脑的更多有趣教程,今天给大家分享扫雷外挂的设计与实现(三)教程,希望对大家能有一点小小的帮助。

  如上述,本程序分为了接口层和算法层。上述全局变量和常量,基本都属于接口层的内容。下面,来看接口层的具体实现。其工作的第一步,是要捕获扫雷窗口并取得其信息。这由函数GetMineWindow来完成:

  =================================================================

  //试图取得可用的扫雷窗口,返回值表示是否成功。若成功,则全局变量
  //MineWnd、MineDC、AreaHeight、AreaWidth都得到相应的填充。若失败,则以上变量的值无意义。

  function GetMineWindow: Boolean;
  var
    clientRect: TRect;
  begin
    result := false;

    MineWnd := FindWindow(nil, MINE_WINDOW_TITLE);           //检查是否存在“扫雷”窗口,并且必须为当前窗口
    if (MineWnd = 0) or (GetForegroundWindow MineWnd) then
      Exit;

    MineDC := GetDC(MineWnd);                                //取得“扫雷”窗口的设备上下文
    if MineDC = 0 then
      Exit;

    GetClientRect(MineWnd, clientRect);                      //检查“扫雷”窗口的内容是否全部显示在屏幕上
    with TCanvas.Create do
      try
        Handle := MineDC;
        if (ClipRect.Left clientRect.Left) or
           (ClipRect.Right clientRect.Right) or
           (ClipRect.Top clientRect.Top) or
           (ClipRect.Bottom clientRect.Bottom) then
          Exit;
      finally
        Free;
      end;

    //从已获得的clientRect中的数值,根据实测数据计算AreaWidth和AreaHeight的值。
    AreaWidth := (clientRect.Right - LEFT_MARGIN - RIGHT_MARGIN) div CELL_WIDTH;
    AreaHeight := (clientRect.Bottom - TOP_MARGIN - BOTTOM_MARGIN) div CELL_HEIGHT;

    //检查游戏是否在进行中,原理为判断“重开始”按钮的图标上的
    //某一像素是否是指定的值。该经验由实测得到,只有游戏进行中,该像素才为该值。
    if TColor(GetPixel(MineDC, AreaWidth*8 + 8, 30)) clBlack then
      Exit;

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)

    result := true;
  end;

  =================================================================

  理解这个函数的工作过程,有几个要点:

  WinAPI函数FindWindow:用来查找当前桌面上的某个窗口。第一个参数是指定该窗口的“窗口类”的名字,这个稍微高深了一点,只有研究过Windows SDK编程才会理解。当它为nil的时候,使用第二个参数,也就是窗口标题栏的字符串来查找。若找到这样一个窗口,则返回值为其窗口句柄,否则为0。

  WinAPI函数GetForegroundWindow:无参数,返回桌面上的当前窗口,也就是标题条加亮的窗口的句柄。

  WinAPI函数GetDC:给定一个窗口句柄,返回它的设备上下文句柄。“设备上下文”实际上就是一个“画布”,在Delphi中,被封装成了TCanvas类。获得了某个设备上下文句柄,就可以用一个TCanvas型的对象指向它(这个过程是,把句柄赋给TCanvas对象的Handle属性),从而实现画布的各种操作。

  WinAPI函数GetClientRect:给定某个窗口句柄,取得它的客户区矩形,这个矩形是一个TRect类型的变量。调用这个函数,要用一个TRect型的变量来接收结果,而不是用返回值。这个结果的Left和Top成员都必定是0,而Right和Bottom成员其实就是窗口客户区的宽和高。

  TCanvas类的属性ClipRect:简单的说,在此处,该TRect型属性取得的是该画布实际上被显示在屏幕上的矩形部分。只有该画布不被其它窗口遮挡,并且没有移出桌面边界的时候,这个矩形才完全等于等于窗口的客户区矩形。这用来判断扫雷窗口是否全部可见。

  WinAPI函数GetPixel:给定一个设备上下文(画布)句柄和X,Y坐标,取得一个像素的值。这个值是整型的,可以简单的强制转换为TColor类型。

  上述库函数,具体说明可以参考MSDN和Delphi自身的帮助文档,可以得到最为权威、详细、正确的说明。

  不得不说一下GetMineWindow函数的最后几行,它牵涉到了对“重开始”按钮的hack。注意一下,可以发现那个简单的脸谱总共有5种状态:平时的笑脸,自身被按下时的笑脸,在雷区中按下鼠标时的紧张表情,触雷时的衰脸和胜利时酷酷的表情~——显然,只有在第一种情况时,扫雷外挂才应该动作,其它四种时则应该停止。我编了一个临时程序,找到了一个像素位置,它只有在第一种情况下值为clBlack,其它情况都不是。它的坐标为(AreaWidth*8 + 8, 30),横坐标是个随方块列数而变的变量,很好理解,因为无论窗口有多宽,该按钮都是水平居中的。

  

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)

  

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)

  

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)

  

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)

  
  

展开更多 50%)
分享

猜你喜欢

扫雷外挂的设计与实现(三)

编程语言 网络编程
扫雷外挂的设计与实现(三)

扫雷外挂的设计与实现(五)

编程语言 网络编程
扫雷外挂的设计与实现(五)

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

扫雷外挂的设计与实现(一)

编程语言 网络编程
扫雷外挂的设计与实现(一)

扫雷外挂的设计与实现(四)

编程语言 网络编程
扫雷外挂的设计与实现(四)

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

扫雷外挂的设计与实现(二)

编程语言 网络编程
扫雷外挂的设计与实现(二)

C# 游戏外挂实现核心代码

编程语言 网络编程
C# 游戏外挂实现核心代码

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

新手入门:JAVA实现数据库基本操作指南

新手入门:JAVA实现数据库基本操作指南

ASP读取XML数据文件的方法

ASP读取XML数据文件的方法
下拉加载更多内容 ↓