这几个月的开发工作主要是关于游戏内GUI的,业务开发之余也时常会看看客户端工程里的GUI系统这一块的代码,这里系统的总结下。

一、GUI树形结构

 

  在GUI中所有的控件都遵循树形结构:



  在客户端初始化时,会创建出一个无形的,跟客户端窗口等大的root窗口:g_FBClient_Global.m_pRootWnd。在游戏中添加的窗口,一般都挂载在root窗口下。要在游戏中新增一个窗口,当在GUI编辑器中创建好了窗口资源后,代码中创建该窗口资源的的方式一般是在对应的类的构造函数中使用:CreateFromRes(strWndResourceName, g_FBClient_Global.m_pRootWnd)。第一个参数是在编辑器中对应窗口资源的名称;第二个为要挂载的父窗口,如前面所述,这里一般都是挂载在根窗口下。该方法成功执行后,该窗口及窗口下的所有子控件便都创建出来了并且都是默认显示的。(关于GUI编辑器的介绍及使用,这个是内部资料了,见/src/Tools/ArkGUIEditor/bin/用ArkGUI创建一个窗口的步骤.doc)

  GUI的绘制时,是在游戏主循环中调用m_pRootWnd->Render(),从根窗口自顶向下地依此树形结构递归地显示绘制。游戏退出时对资源的回收,也是如此进行的(所以在窗口中创建的控件,如果在创建时挂载在了该窗口下的话,都无需自己手动释放)。

二、关于CArkWnd类

  class CArkWnd;是所有窗口和控件的基类。其中绝大部分为虚方法,包括窗口生命周期函数如OnCreated()、OnDestroy()、OnUpdateDataBeforeDraw()等;响应消息的一些函数如OnMouseWheel()、OnChildmsg()以及设置窗口属性功能的函数如EnableWnd()、SetFontSize()、SetWndText()等。

  一个窗口的生命周期大致可以表示如下:



一些常用的控件:

  1. 按钮类

      像按钮CArkButton、复选框CArkCheckoutButton等的显示,是在GUI编辑器中设置了一个按钮的各个状态的贴图包括点击、鼠标经过、禁用等状态。 按钮自己接收到鼠标事件进行不同状态的响应,在重写的虚函数DrawWndBackground()中实现:

    void CArkButton::DrawWndBackground()
    {
    DrawBackImage(m_pWndData->m_Enable,m_pWndData->m_Disable,
    m_MouseOverImage,m_ClickDownImage,IsHeld());// 传入各个状态的图片链表
    }
  2. 富文本框

      游戏内大部分显示文本的地方都是使用的富文本控件,最典型的像任务描述面板和聊天面板。在富文本框中的文字可以设置字体风格颜色及换行。

      通过CArkRichText和CArkRichTextFormat进行换行和颜色解析等功能的具体实现。(RichWnd格式化文字说明(内部网址):http://192.168.1.252:8080/pages/viewpage.action?pageId=9110273)

  3. 其他常用的控件还有诸如文本编辑框CArkEdit、泡泡提示框CTorchbearerWnd、确认框/确认取消框CRichMsgBox等等。

三、消息响应

  一个消息响应流程大致如下:

  由根窗口接收到消息:

  g_FBClient_Global.m_pRootWnd->ReceiveMsg(message, wParam, lParam);

  再由CArkWnd类中的窗口管理器CArkGUIManage,调用:pGUI->WndProc(message,wParam,lParam);

  在这个函数中分别处理鼠标消息和键盘消息:

  CArkMouseMsgProc::ProcessMsg(uint32 message, WPARAM wParam, LPARAM lParam)

  CArkKeyMsgProc::ProcessMsg(uint32 message, WPARAM wParam, LPARAM lParam)

  在上面的处理函数中,会找到最顶层的CArkWnd窗口,也就是我们在界面上实际操作的控件。然后调用这个CArkWnd的方法:

  CArkWnd::WndProc(uint32 message, WPARAM wParam, LPARAM lParam)

  在WndProc函数中,根据消息类型执行对应的处理函数;假设我们是点击了某个按钮,那么根据消息为点击事件,就执行虚方法OnLButtonDown()。那么实际就是由按钮类CarkButton的OnLButtonDown函数执行,在里面做一些特殊操作例如播放该按钮被点击时的特效。

  在平时GUI的开发中最主要接触的是这个OnChildMsg函数。在自己编写的窗口中,由这个函数的pChild和uMsgID参数得到子控件名称和消息类型,就能确定在界面上进行了什么操作,然后做后续的业务逻辑;比如在商城点击了“购买”按钮,那么当GenWndName(pChild)== ”BuyBtn”&& uMsgID==BUTTON_CLICK时就响应BuyItem()函数发消息给服务器。

  大致流程还可以看下面这张图:

客户端GUI结构学习总结的更多相关文章

  1. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  2. 机器学习&数据挖掘笔记_24(PGM练习八:结构学习)

    前言: 本次实验包含了2部分:贝叶斯模型参数的学习以及贝叶斯模型结构的学习,在前面的博文PGM练习七:CRF中参数的学习 中我们已经知道怎样学习马尔科夫模型(CRF)的参数,那个实验采用的是优化方法, ...

  3. Linux 目录结构学习与简析 Part2

    linux目录结构学习与简析 by:授客 QQ:1033553122 ---------------接Part 1-------------- #1.查看CPU信息 #cat /proc/cpuinf ...

  4. Linux 目录结构学习与简析 Part1

    linux目录结构学习与简析 by:授客 QQ:1033553122 说明: /             linux系统目录树的起点 =============== /bin      User Bi ...

  5. C++ GUI Qt4学习笔记01

    C++ GUI Qt4学习笔记01   qtc++signalmakefile文档平台 这一章介绍了如何把基本的C++只是与Qt所提供的功能组合起来创建一些简单的图形用户界面应用程序. 引入两个重要概 ...

  6. C++ GUI Qt4学习笔记03

    C++ GUI Qt4学习笔记03   qtc++spreadsheet文档工具resources 本章介绍创建Spreadsheet应用程序的主窗口 1.子类化QMainWindow 通过子类化QM ...

  7. C++ GUI Qt4学习笔记08

    C++ GUI Qt4学习笔记08   qtc++signal图形引擎文档 本章介绍Qt的二维图形引擎,Qt的二维图形引擎是基于QPainter类的.<span style="colo ...

  8. C++ GUI Qt4学习笔记09

    C++ GUI Qt4学习笔记09   qtc++ 本章介绍Qt中的拖放 拖放是一个应用程序内或者多个应用程序之间传递信息的一种直观的现代操作方式.除了剪贴板提供支持外,通常它还提供数据移动和复制的功 ...

  9. C++ GUI Qt4学习笔记05

    C++ GUI Qt4学习笔记05   qtc++正则表达式 QIntValidator           --  只让用户输入整数 QDoubleValidator     --  只让用户输入浮 ...

随机推荐

  1. 锁、volatile、CAS的比较

    一.锁 锁是一种悲观的机制.为多线程提供了互斥的访问机制.多个线程同时竞争锁时,没获得锁的线程将会被挂起(智能的JVM会根据之前获取锁操作中对锁的持有时间长短来判断是使线程挂起还是自旋) 锁的劣势:1 ...

  2. $2019$各种$WC$没去记

    \(2019\)各种\(WC\)没去记 太弱了去不了啊. 至少我联赛没退役是吧...(退役感++ 不过这个分数线还是有点让人自闭啊,划线人绝对有毒,有人关照一下空巢老人\(mona\)喵? 这里大概是 ...

  3. 解决安装mysql-connector-odbc-5.3.2 错误1918……不能加载安装或转换器库……的BUG

    还是在虚拟机Windows Server 2003上安装mysql-connector-odbc-5.3.2,装着装着就报错了,大致是“错误1918……不能加载安装或转换器库……”,问我Retry,I ...

  4. Python获取exe文件版本

    import time, datetime, re, subprocess, sys, os, win32net, win32api, win32con, win32netcon, win32secu ...

  5. vue开发可复用组件

    组件,是一个具有一定功能,且不同组件间功能相对独立的模块.高内聚.低耦合.   开发可复用性的组件应遵循以下原则:   1.规范化命名:组件的命名应该跟业务无关,而是依据组件的功能命名. 2.数据扁平 ...

  6. navicat的使用(测试库和正式库同步)以及用plsql改表字段属性

    说明:数据库的操作,除了查询,最好先做好备份,比如数据同步.更新.修改或删除之类的: netstat -antp   查看mysql端口 firewall -cmd --list-all    查看防 ...

  7. spring boot整合WebSocket示例

    1.运行环境 开发工具:intellij idea JDK版本:1.8 项目管理工具:Maven 4.0.0 2.GITHUB地址 https://github.com/nbfujx/springBo ...

  8. 超大文件上传方案(B/S)

    javaweb上传文件 上传文件的jsp中的部分 上传文件同样可以使用form表单向后端发请求,也可以使用 ajax向后端发请求 1.通过form表单向后端发送请求 <form id=" ...

  9. [CSP-S模拟测试]:飞(fly)(数状数组+简单几何)

    题目描述 $liu\_runda$决定提高一下知识水平,于是他去请教郭神.郭神随手就给了$liu\_runda$一道神题,$liu\_runda$并不会做,于是把这个题扔到联考里给高二的做.郭神有$n ...

  10. 转载:TypeError: Cannot read property 'compilation' of undefined vue 打包运行npm run build 报错

    转载自:https://www.jianshu.com/p/3f8f60e01797 运行npm run build打包时,报错如下:   我的package.json如下: { ... " ...