扫雷___核心鼠标逻辑

鼠标逻辑是扫雷最核心的部分。我们需要根据当先前鼠标位置,所在方块的状态和历史状态,游戏状态等等来综合考虑界面的体现
     所需要的状态量:

     雷状态:正常STATE_NORMAL,空STATE_EMPTY,未知STATE_DECKY,未知按下状态STATE_DECKY_DOWN 红旗STATE_FLAG
     游戏状态:等待GS_WAIT 运行GS_RUN 失败GS_DEAD 成功GS_VICTORY
     为了实现方块体现状态(未知 正常 红旗 等)和方块内部状态(方块是否为雷)的独立 需要分别用两个量来表示
     为了实现鼠标移动时的动态变化,每一个雷方块有两个状态 原本状态 和 现在状态
     以下是方块结构定义
     

     这一块不是很复杂 但是很繁杂 不知道怎么整理 做的时候是一点一点的改动和修正累积的。
     主要就是在实现鼠标逻辑的时候,会有很多分支:
     鼠标的点击区域(笑脸区域, 雷区域, 其他区域)
     游戏的状态(等待开始,运行中,失败,成功)
     当前鼠标所在的位置的雷方块m_pNewMine状态(标识,正常,未知,等)
     上一刻鼠标所在位置的雷方块m_pOldMine状态

     这些都涉及到分支,使得程序很难控制每一个分支的流程都能够得到正确效果,分支的跳出是用break,continue,还是return 以及分支该跳出到哪一层,都会影响到整个程序的结构是否复杂凌乱
     由于鼠标每一次点击都会对应笑脸的响应 因此改动分支后经常会遇到笑脸状态异常或者不能恢复等情形。
    我的代码在整体上肯定是很糟糕凌乱的,很多该划分的子模块没有划分,以及对整个分支流程的控制也很差。
     具体鼠标逻辑可以参见源代码。
源代码下载地址点击这里(本人资源分寥寥无几了,所以...咳 别说我不厚道啊。如果哪位和我一样穷的话,就留言吧,我发给他,)
     http://download.csdn.net/detail/wudaijun/4709630
     接下来 我总结一下在鼠标逻辑控制时遇到的一些问题和得到的教训
     1.如果实现鼠标对方块的动态选择:
          每个雷快设置两个标识域(uState,uOldState)用于恢复 设置两个成员变量用于表示此刻(m_pNewMine)和上一刻(m_pOldMine)的选取方块 当鼠标移动时 按下m_pNewMine并且松开m_pOldMine
     2.如何扩展雷:
          当选中的方块周围没有雷时,对该方块周围的方块进行扩展 如果周围有雷 则绘制雷的数目 如果没有 再递归扩展该方块周围
     3.如何得到或相应鼠标左右键同时按下:
          在OnLButtonDown或OnRButtonDown中如果nFlags==(MK_LBUTTON|MK_RBUTTON)即可识别。如果要响应其中任何一个键松开的消息。可以通过设置一个成员变量m_bLRBtnDown实现,在OnMouseMove中直接判断并且做相应的事情。而在OnL(R)ButtonUp中 需要立即将其置为假 
          if(m_bLRBtnDown)
          {
               m_bLRBtnDown = FALSE;//避免在放开一个键后 还在响应双键移动消息
               。。。。
          } 

以上所的m_bLRBtnDown的设置与恢复均需要在左键和右键中同时实现,因为左右键的按下和放开不会是绝对同时的,只有在一个左键按下后立即按右键 才能在右键的RButtonDown中得到nFlags==(MK_LBUTTON|MK_RBUTTON) 反之亦然
     4.其他一些比较小的逻辑 如边界处理 胜利与失败的判定 等等 在雷方块结构体和一些必要的信息获取的函数确认之后都比较简单 本身不涉及什么算法。此处省略
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章