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

2016-02-19 19:31 11 1 收藏

今天给大家分享的是由图老师小编精心为您推荐的扫雷外挂的设计与实现(四),喜欢的朋友可以分享一下,也算是给小编一份支持,大家都不容易啊!

【 tulaoshi.com - 编程语言 】

  不得不说,捕获“扫雷”窗口以及取得它的数据,是本程序的一个难点。现在这个难点已经解决,接下来,完成接口层已经不是问题了。那么,来看接口层的两个核心过程:

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

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

  //取得整个雷区每个方块的状态,填入Cells中供分析。
  procedure FetchCells;
  var
    i, j: Integer;
  begin
    //扫描每个方块,根据指定像素的颜色判断该方块的性质。
    //特定像素的颜色与方块性质的对应关系归纳自“扫雷”程序本身的资源。
    for i:=0 to AreaWidth-1 do
    for j:=0 to AreaHeight-1 do
      //首先判断(0, 0)点的像素
      case TColor(GetPixel(MineDC, LEFT_MARGIN + i*CELL_WIDTH, TOP_MARGIN + j*CELL_HEIGHT)) of
        clWhite:
          //是未挖开的方块,再判断(5, 4)点的像素
          case TColor(GetPixel(MineDC, LEFT_MARGIN + i*CELL_WIDTH + 5, TOP_MARGIN + j*CELL_HEIGHT + 4)) of
            clSilver: Cells[i, j] := csUnknown;     //未翻开的方块
            clRed: Cells[i, j] := csMarked;           //已标记为雷的方块
            clBlack: Cells[i, j] := csPossible;      //标问号的方块
          end;
        clGray:
          //是已挖开的方块,再判断(7, 4)点的像素
          case TColor(GetPixel(MineDC, LEFT_MARGIN + i*CELL_WIDTH + 7, TOP_MARGIN + j*CELL_HEIGHT + 4)) of
            clSilver: Cells[i, j] := cs0;    //空白,相当于数字0
            clBlue: Cells[i, j] := cs1;      //数字1
            clGreen: Cells[i, j] := cs2;     //数字2
            clRed: Cells[i, j] := cs3;       //数字3
            clNavy: Cells[i, j] := cs4;      //数字4
            clMaroon: Cells[i, j] := cs5;    //数字5
            clTeal: Cells[i, j] := cs6;      //数字6
            clBlack: Cells[i, j] := cs7;     //数字7
            clGray: Cells[i, j] := cs8;      //数字8
          end;
      end;
  end;

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

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

  以上程序中,三个包含 case...of 的行,都用到了前面实测到的数据。执行完之后,扫雷窗口所有方块的状态就原原本本地在输入缓冲区里了。

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

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

  //将Operations中所记载的对每个方块的操作真正作用于扫雷窗口。
  procedure OperateCells;
  var
    i, j: Integer;
    downMsg, upMsg: Cardinal;     //按下和抬起鼠标按钮时分别发送的消息
    wparam, lparam: Integer;      //消息参数
    clickCount: Integer;          //按键次数,只有取值1或2
  begin
    //扫描每个方块
    for i:=0 to AreaWidth-1 do
    for j:=0 to AreaHeight-1 do
    begin
      if Operations[i, j] = opNone then
        Continue;
      //根据操作种类,设定发送的消息及其参数
      lparam := ((TOP_MARGIN + j*CELL_HEIGHT) shl 16) + (LEFT_MARGIN + i*CELL_WIDTH);
      wparam := IfThen(Operations[i, j] = opBothClick, MK_RBUTTON, 0);
      downMsg := IfThen(Operations[i, j] in [opRightClick, opRightDoubleClick], WM_RBUTTONDOWN, WM_LBUTTONDOWN);
      upMsg := IfThen(Operations[i, j] in [opRightClick, opRightDoubleClick], WM_RBUTTONUP, WM_LBUTTONUP);
      //设定发送消息次数,即单击还是双击
      clickCount := IfThen(Operations[i, j] = opRightDoubleClick, 2, 1);
      //发送消息
      repeat
        PostMessage(MineWnd, downMsg, wparam, lparam);
        PostMessage(MineWnd, upMsg, wparam, lparam);
        Dec(clickCount);
      until clickCount = 0;
    end;
  end;

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

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

  这里需要说的是WM_LBUTTONDOWN、WM_LBUTTONUP、WM_RBUTTONDOWN和WM_RBUTTONUP四个消息。它们是在一个窗口客户区内按下或抬起鼠标左或右按钮时,发给这个窗口的消息。所以,手动地发送这些消息,其实就是模拟鼠标的点击。发送消息用到了WinAPI函数PostMessage,它和大家所熟悉的SendMessage函数的参数是相同的,作用也几乎相同,主要区别是不等待消息的返回,详见MSDN。上述四个消息的WParam和LParam都具有同样的意义:WParam用来指定按下该键的时候,还有哪些其它特定的键(其它鼠标键,或Ctrl,Shift等)被按下。0表示没有其它键被按下,在这里还用到了值MK_RBUTTON,即按下左键时指定右键同时也被按下,用来模拟同时按下左右键的情况。当然,发送RBUTTONDOWN和RBUTTONUP时指定MK_LBUTTON也是同样的效果。而LParam则指定了按下或抬起键时鼠标指针的坐标,它的高16位为Y坐标,低16位为X坐标。给lparam赋值的那一行,就是把X,Y两个值组装成了一个lparam。

  另外提一下IfThen函数,这个函数平时并不见有多人使用,但它真的很方便,至少它解决了对于“Delphi中没有C的 ? : 运算符”的抱怨^_^。不错,这就是Delphi的问号运算符,三个参数中第一个是Boolean型,若为真,返回值就是第二个参数,否则是第三个参数。第二、第三个参数类型相同,并且有多个重载版本。数值版本需要包含Math库,而字符串版本需要StrUtils库。显然,编译上述代码是需要包含Math库的。若不愿,当然你也可以使用 if...then。

  至此,接口层全部实现完毕,接下来就可以安心的实现“数学模型”了。

来源:http://www.tulaoshi.com/n/20160219/1621238.html

延伸阅读
摘 要 :介绍了XML应用中合并XML文档的方法与应用,在基于XML的应用中,有着广泛的应用前景。 关键词 :XML文档 解析器 元素 在XML应用中,最常用也最实用的莫过于XML文件的读写。由于XML语义比较严格,起始标记必须配对,所以合并XML文档并不像合并普通文件那样简单。在JAVA中,如何合并XML文档,下面介绍一种方法。 设计思想 应用ja...
摘要 Struts是目前Web开发中比较成熟的一种框架,本文阐述了基于MVC模型的Web应用软件开发框架struts的体系结构及主要组成组件,并结合一个实例讨论如何设计基于struts框架的应用,同时也分析了使用struts框架开发web应用的优势。 要害词 Struts;模型;视图;控制器 近年来,基于MVC(Model-View-Controller)模型的Stru...
标签: Web开发
随着Internet的普及和电子商务的兴起,网上书店是Internet电子商务在图书销售行业发展的必然结果。这种新型的图书销售形式,与传统利用书店进行销售的方式相比,网上书店拥有许多优势:一是降低了销售成本;二是利用网络作为交易平台,改变了传统的交易方式,使得交易活动不受空间和时间的限制;同时,信息的传递更迅速灵活,新书信息上传...
template class CToolbar { public: CToolbar(); void CreateToolbar(HWND hParent);// 创建工具条 void AddButtons();// 逐个加入按钮 void DestroyToolbar();// 撤消工具条 LRESULT OnToolbarNeedText(WPARAM, LPNMHDR pnmh, BOOL&); // 工具条上按钮的提示信息 protected: ...
进入游戏 在这里我们以最基础的开始学习,以初级游戏为基础,打开软件,开始→所有程序→游戏→扫雷;启动游戏后能看到这么一个窗口。 开始游戏 点击笑脸,则开始游戏计时。计时器位于右侧,总雷数位于左侧,扫除一个则左侧数字减少一个。 随意点击 红框的地方是告诉你在这个游戏中总共有几个地雷。上来是没有办法的,第一步只能随...

经验教程

359

收藏

50
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部