文章目录

  • 前言
  • 一、游戏规则分析?
  • 二、使用SOUI创建基本界面
    • 1.创建一个类CMine代表一个格子
    • 2.对应XML
    • 3.调用createMine动态创建格子
    • 4.响应EventCBSelChange动态生成界面
  • 总结

前言

扫雷是Windows内置经典游戏之一!它是一个简单的数字逻辑推理游戏!


一、游戏规则分析?

游戏规则很简单,用户通过鼠标点击分布的格子,点击的结果有三种:雷,数字,空白!如果是雷则本局失败,数字则表明此格子周围八个格子的雷数量,空白则自动打开附近的区域直到没有连续空白格子!此外游戏还提供一个右键标注功能,通过右击可以标注推测结果避免误点和帮助分析!

二、使用SOUI创建基本界面

1.创建一个类CMine代表一个格子

代码如下(示例):

#include <core/SWnd.h>
#include <vector>
#include <layout/SGridLayout.h>
#include <sstream>/// <summary>
/// 标记格子状态
/// </summary>
enum class MINE_STATE {normal,//常规flag,//标记open//打开
};#define ICON_MAX_INDEX 4
/// <summary>
/// 代表一个雷区格子
/// </summary>
class CMine
{MINE_STATE m_mineState = MINE_STATE::normal;
private:SWindow* _pWnd = nullptr;int _iiconIndex = 0;size_t _uminecount = 0;
public:CMine(){}SWindow* getWnd(){return _pWnd;}void reset(){m_mineState = MINE_STATE::normal;_iiconIndex = 0;_pWnd->EnableWindow(TRUE);}void attackWnd(SWindow* pWnd){SASSERT(pWnd);SASSERT(!_pWnd);_pWnd = pWnd;}~CMine(){}//获取状态MINE_STATE getState()const {return m_mineState;}//是否点开bool isOpen()const {return m_mineState == MINE_STATE::open;}//是否可以左键点击bool canLClick()const {return m_mineState == MINE_STATE::normal;}//是否可以右键点击bool canRClick()const {return m_mineState != MINE_STATE::open;}//获取图标绘制状态int getCurIndex()const {return _iiconIndex;}//获取图标绘制状态int getNextIndex() {++_iiconIndex;SASSERT(_iiconIndex >= 0);if (_iiconIndex >= ICON_MAX_INDEX)_iiconIndex = 0;return _iiconIndex;}
public:
#define MAX_COL 16
#define MAX_ROW 30#define MIN_COL 9
#define MIN_ROW 9/// <summary>/// 创建一个雷区/// </summary>/// <param name="parent">雷区窗口模板</param>/// <param name="strName">雷区窗口模板</param>/// <param name="mines">雷区数据</param>/// <param name="row">行</param>/// <param name="col">列</param>/// <returns></returns>static std::vector<std::vector<CMine>>& createMine(SWindow* parent, const SStringT& strName, std::vector<std::vector<CMine>>& mines, const size_t col, const size_t row){SASSERT(parent);if (!parent)return mines;{SGridLayout* param = sobj_cast<SGridLayout>(parent->GetLayout());SASSERT(param);std::wstringstream os;os << col;param->SetAttribute(L"columnCount", os.str().c_str());}for (auto& ite1 : mines){for (auto& ite2 : ite1){SWindow* _pWnd = ite2.getWnd();if (_pWnd){SWindow* _Parent = _pWnd->GetParent();if (_Parent){_Parent->DestroyChild(_pWnd);}}}}mines.clear();mines.resize(row);for (int r = 0; r < row; r++){mines[r].resize(col);}SStringW strXml = GETTEMPLATEPOOLMR->GetTemplateString(strName);SASSERT(!strXml.IsEmpty());if (!strXml.IsEmpty()){pugi::xml_document xmlDoc;if (xmlDoc.load_buffer_inplace(strXml.GetBuffer(strXml.GetLength()), strXml.GetLength() * sizeof(WCHAR), 116, pugi::encoding_utf16)){pugi::xml_node xmlTemp = xmlDoc.first_child();SASSERT(xmlTemp);for (int r = 0; r < row; r++)for (int c = 0; c < col; c++){SWindow* pChild = SApplication::getSingleton().CreateWindowByName(xmlTemp.name());if (pChild){parent->InsertChild(pChild);pChild->InitFromXml(xmlTemp);mines[r][c].attackWnd(pChild);}}}}return mines;}};

这里使用createMine创建一个二维数据,每次创建都会销毁前面的窗口,暂不考虑优化问题。

2.对应XML

template.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<template>  <mine><window skin="mine_bkskin" size="26,26" columnWeight="1" rowWeight="1"><img name="flag" pos="|,|" show="0" offset="-0.5,-0.5" size="-1,-1"/><text name="minecount" pos="|,|" show="0" offset="-0.5,-0.5" size="-1,-1" text="1"/></window></mine>
</template>

uires.idx的values节点下添加:

<values><file name="string" path="values\string.xml"/><file name="color" path="values\color.xml"/><file name="skin" path="values\skin.xml"/><file name="template" path="values\template.xml"/></values>

init.xml 在节点添加template节点下添加:

<template src="values:template"/>

dlgmain.xml修改如下,添加了一个combobox用于选择难度。

<SOUI name="mainWindow" title="@string/title" bigIcon="ICON_LOGO:32" smallIcon="ICON_LOGO:16" margin="5,5,5,5"  resizable="0" wndType="appMain"
appWnd="1"
translucent="1"
><root skin="_skin.sys.wnd.bkgnd" cache="1" size="-1,-1" layout="vbox"><caption size="-2,30" font="adding:0"><icon pos="10,8" src="ICON_LOGO:16"/><text pos="29,9">@string/title</text><imgbtn name="btn_close" skin="_skin.sys.btn.close" pos="-45,0" tip="close" animate="1"/><imgbtn name="btn_min" skin="_skin.sys.btn.minimize" pos="-83,0" animate="1" /></caption><combobox name="cbx_lv" size="200,30" dropDown="1" dropHeight="300" dotted="0" animateTime="200" curSel="0"><liststyle itemHeight="30" colorText="#000000" colorSelText="#FFFFFF" colorItemBkgnd="#FFFFFF" colorItemSelBkgnd="#000088" /><editstyle inset="5,0,5,0" margin="0" colorText="#000000" align="left" colorBkgnd="#FFFFFF" /><items><item text="初级" icon="1" data="0" /><item text="中级" icon="2" data="1" /><item text="高级" icon="3" data="2" /></items></combobox><window name="parent_mine" size="-1,-1" padding="6,6,6,6" layout="gridLayout" columnCount="4" xGravity="fill" yGravity="fill"/></root>
</SOUI>

3.调用createMine动态创建格子

BOOL CMainDlg::OnInitDialog(HWND hWnd, LPARAM lParam)
{CMine::createMine(FindChildByName(L"parent_mine"), L"mine", m_mines, 9, 9);bInit = true;return 0;
}

其中两个变量定义为

bool bInit = false;
std::vector<std::vector<CMine>> m_mines;

4.响应EventCBSelChange动态生成界面

添加事件映射

EVENT_NAME_HANDLER(L"cbx_lv", EventCBSelChange::EventID, OnCbxLvChange)

OnCbxLvChange函数实现如下:

void CMainDlg::OnCbxLvChange(EventArgs* e)
{if (!bInit)return;EventCBSelChange* e2 = sobj_cast<EventCBSelChange>(e);SComboBox* pCbx = sobj_cast<SComboBox>(e2->sender);if (e2->nCurSel != -1){LPARAM lv = pCbx->GetItemData(e2->nCurSel);switch (lv){case 0:CMine::createMine(FindChildByName(L"parent_mine"), L"mine", m_mines, 9, 9);break;case 1:CMine::createMine(FindChildByName(L"parent_mine"), L"mine", m_mines, 20, 12);break;case 2:CMine::createMine(FindChildByName(L"parent_mine"), L"mine", m_mines, 30, 16);break;}     }
}

最后运行效果如下:

总结

SOUI是一个强大的UI库,可以方便实现静态XML或动态创建工作。

SOUI实例之扫雷一相关推荐

  1. 推荐一本书:《Visual C++程序开发范例宝典》——你可以找到你想要的实例

    废话少说,先上<Visual C++程序开发范例宝典>的目录: 目录: 第1章 窗体与界面设计 1 1.1 菜单应用实例 2 实例001 在系统菜单中添加菜单项 2 实例002 带图标的程 ...

  2. 下载频道2013年超人气精华资源汇总---全都是免积分下载

    .Net 1.C#入门到精通加强版 2.C#类库查询手册 Android 3.最新android ADT-21.1.0 4.Android开发精典案例60个[源码] 5.安卓开发必学书籍(30本合集) ...

  3. 下载频道2013下半年超人气精华资源汇总---全都是免积分下载。

    下载频道2013下半年超人气精华资源汇总---全都是免积分下载. 十分感谢这些免积分分享精华资源的好人!! 转自:http://bbs.csdn.net/topics/390674613 Androi ...

  4. 前端开发基础知识汇总

    一.HTML 1.前言与常用标签 浏览器 内核 备注 IE Trident IE.猎豹安全.360极速浏览器.百度浏览器 firefox Gecko 可惜这几年已经没落了,打开速度慢.升级频繁.猪一样 ...

  5. Spring Cloud微服务系统架构的一些简单介绍和使用

    Spring Cloud 目录 特征 云原生应用程序 Spring Cloud上下文:应用程序上下文服务 引导应用程序上下文 应用程序上下文层次结构 改变Bootstrap的位置Properties ...

  6. python扫雷的代码及原理_基于Python实现的扫雷游戏实例代码

    摘要:这篇Python开发技术栏目下的"基于Python实现的扫雷游戏实例代码",介绍的技术点是"Python实现.Python.实例代码.扫雷游戏.扫雷.游戏" ...

  7. php游戏实例,php实现的简易扫雷游戏实例_PHP

    本文实例讲述了php实现的简易扫雷游戏.分享给大家供大家参考.具体如下: = 0 && $j - 1 >= 0 && $data["data" ...

  8. python扫雷游戏实验分析_用python写扫雷游戏实例代码分享

    扫雷是一个非常经典的WIN游戏,我们教给大家用python语言来写出这个游戏,以下是全部实例代码: #!/usr/bin/python #coding:utf-8 #python 写的扫雷游戏 imp ...

  9. python游戏脚本实例-基于Python实现的扫雷游戏实例代码

    本文实例借鉴mvc模式,核心数据为model,维护1个矩阵,0表无雷,1表雷,-1表已经检测过. 本例使用python的tkinter做gui,由于没考虑可用性问题,因此UI比较难看,pygame更有 ...

  10. SOUI中心事件的使用实例

    首先使用SOUI的向导建立一个工程 需要注意以下几点: 首先要包含 notifycenter.h这个头文件,这个头文件工程默认是不会添加的,验证方法使用SNotifyCenter在程序的任何一个地方会 ...

最新文章

  1. mysql设计数据集市_数据集市设计
  2. PE学习(十)第十章: 加载配置信息表
  3. Android接入支付宝支付实现
  4. Navigation Drawer介绍
  5. PIX的AAA认证配置
  6. 微信小程序uni.switchTab传参获取不到;小程序跳转到tabBar页并传参;uni-app微信小程序获取tabBar页面参数失败;uni-app微信小程序tabBar页面onLoad不执行
  7. html页面导出,HTML页面导出execl表格
  8. 5 年 Python 的我,总结了这 90 条写 Python 程序的建议
  9. linux环境下的TIME_WAIT和CLOSE_WAIT问题解决方法
  10. 使用Tushare进行公司数据分析
  11. Premiere视频导出格式
  12. i2c电路电平转换电路
  13. java x86 x64_jdk x86与jdk x64 有什么区别
  14. android 右边抽屉,android双抽屉:右抽屉切换
  15. SQL Server 日期 字符串 格式转换 函数 datetime convert
  16. 利用吉洪若夫正则化及其西尔韦斯特方程来修复受损图像
  17. Android开发之麦田福音网移动版本演示程序
  18. 跟这台计算机连接的一个usb设备运行不正常windows无法识别,win10跟这台计算机连接的一个usb设备运行不正常怎么办...
  19. 拯救者R9000X显卡驱动安装
  20. 在Java中操作MySQL(JDBC)

热门文章

  1. 团体程序设计天梯赛-练习集——7-9 打印学生选课清单 (25分)
  2. 22021成都市高考成绩查询,四川大学本科教务系统登录
  3. iOS 实现时间线列表效果
  4. python参考文献及其出版社_金融工程及其Python应用(高等院校财政金融专业应用型教材) 正版 朱顺泉 9787302510758_朱顺泉_孔夫子旧书网...
  5. 程序员因为写了一段爬虫代码,全公司200人被警察一锅端!
  6. 图像相似度对比分析软件,图像相似度计算方法
  7. NetSetMan NetSetMan IP快速切换
  8. 鲁棒控制器设计方法(systune,hinfsyn,musyn...)
  9. Appium环境搭建超详细教程
  10. m115b linux 驱动下载,富士施乐m115b驱动