《Windows游戏编程大师技巧》学习笔记(五)

创建菜单

菜单的配置与前述各类资源一样,编写在.RC资源脚本中,同时,和字符串资源相似,菜单各项的标识符也必须是整数ID,而不能是名称字符串;
一个简单的菜单配置如下:

1
2
3
4
5
6
7
// 在头文件 RESOURCES.H 中
#define MENU_FILE_ID_OPEN 1000
#define MENU_FILE_ID_CLOSE 1001
#define MENU_FILE_ID_SAVE 1002
#define MENU_FILE_ID_EXIT 1003

#define MENU_HELP_ABOUT 2000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 在资源脚本 xxx.RC 中
MainMenu MENU DISCARDABLE
{
POPUP "File"
{
MENUITEM "Open", MENU_FILE_ID_OPEN
MENUITEM "Close", MENU_FILE_ID_CLOSE
MENUITEM "Save", MENU_FILE_ID_SAVE
MENUITEM "Exit", MENU_FILE_ID_EXIT
}

POPUP "Help"
{
MENUITEM "About", MENU_HELP_ABOUT
}
}

上述代码可以生成如下图所示的菜单栏:

带有两个下拉菜单的菜单条

作者在书中写道“关键字DISCARDABLE是过时了但还是必须的”,但是实测在VisualStudio2019环境下此声明是不需要的
与其他资源的定义相同,花括号可以被替换为BEGIN...END对;
如果需要设置热键或配合Alt触发的快捷键,只需要在POPUP菜单或MENUITEM字符串中将&放到想要标识的快捷键字符前面,如下:

1
2
3
4
5
// 使 x 成为热键
MENUITEM "E&xit", MENU_FILE_ID_EXIT

// 设置可以通过 Alt+F 触发的快捷键
POPUP "&File"
阅读更多

《Windows游戏编程大师技巧》学习笔记(四)

资源与Windows应用程序

Windows程序支持将资源数据编译到.EXE文件中,优势如下:

  • 更容易发布
  • 不易丢失附加资源
  • 无法被轻易访问和修改

资源与Windows应用程序关系

支持编译到程序中的资源类型有:图标,光标,字符串,声音,位图,对话框,图元文件
我们只需要创建扩展名为.RC的文本文件,资源编译器会自动根据所配置的资源脚本装载所需的资源,并编译到以.RES为扩展名的文件中,后续与.LIB.OBJ文件编译为一个完整的应用程序文件;

编译及链接时的资源数据流程

阅读更多

控制台字符游戏开发库

控制台字符画可谓是程序员永远的浪漫~

前不久有朋友问我:如何实现控制台的飞机大战游戏,想来想去,控制台游戏我玩过,飞机大战我也写过,逻辑也并不复杂,但是控制台飞机大战还真没有做过,控制台没有方便的图形API,如何实现简单高效地绘图恐怕是最大的问题;
转念一想,类比图形API,控制台下每一个字符都可以被视作一个单独的像素,图片便是字符串数组,而二维的字符数组就可以充当渲染缓冲区,调用printf进行输出的操作就可以当成是将渲染缓冲区的数据拷贝至显示器的操作,这样来看,完全可以从头设计一套简单的控制台图形API来方便将游戏数据显示到屏幕上;

阅读更多

B站直播间弹幕互动小游戏制作

弹幕游戏开发框架

不久之前做了一个直播间弹幕互动小游戏的开发框架,不过一直没有把相关的内容记录下来,也没有使用这个框架完成一部完整的、具有游戏性的小游戏,所以正好忙里偷闲整理一篇博文,顺带做一款大地图的多人扫雷。

本篇主要对框架的技术设计进行阐述,游戏逻辑等日后有机会再另其一篇文章进行介绍;

阅读更多

《Windows游戏编程大师技巧》学习笔记(三)

实用的Windows应用程序概要

Windows程序的关键是打开窗口,并对窗口进行文本、图像的显示工作,以及对来自窗口的交互消息做出响应,步骤如下:

  1. 创建一个Windows类;
  2. 创建一个事件句柄或WinProc回调函数;
  3. 注册先前创建的Windows类到Windows系统中;
  4. 用注册过的Windows类创建一个窗口;
  5. 创建一个能从事件句柄获取事件或向事件句柄传递Windows信息的事件循环。

Windows类

每一个应用程序至少需要创建一个Windows类,用于描述窗口信息;
描述Windows类信息的数据结构有两个,WNDCLASSWNDCLASSEX,最好选用较新的扩展版本WNDCLASSEX
在Unicode环境下,WNDCLASSEXW被定义成了WNDCLASSEX,相关定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
typedef struct tagWNDCLASSEXW {
UINT cbSize; // 结构体大小
/* Win 3.x */
UINT style; // 样式
WNDPROC lpfnWndProc; // 窗口事件回调函数指针
int cbClsExtra; // 额外的类信息
int cbWndExtra; // 额外的窗口信息
HINSTANCE hInstance; // 应用程序实例句柄
HICON hIcon; // 主图标句柄
HCURSOR hCursor; // 鼠标句柄
HBRUSH hbrBackground; // 窗口背景填充笔刷句柄
LPCWSTR lpszMenuName; // 需要附加的菜单名
LPCWSTR lpszClassName; // 类本身的名字
/* Win 4.0 */
HICON hIconSm; // 小图标句柄
} WNDCLASSEXW, *PWNDCLASSEXW, NEAR *NPWNDCLASSEXW, FAR *LPWNDCLASSEXW;
阅读更多

《Windows游戏编程大师技巧》学习笔记(二)

多任务和多线程

Windows允许不同的应用程序以轮询的方式“同时”执行,每一个应用程序都占用一段很短的时间片来运行,而后轮到下一个应用程序运行,如下图所示,CPU由几个不同的应用程序以循环的方式共享,而负责判断出下一个运行的程序、给每个程序分配运行时间的是调度程序的工作:

调度程序示意图

  • 简单的调度策略:给每个应用程序分配固定的运行时间;
  • 复杂的调度策略:将应用程序设定为不同的优先级和抢先性或低优先级的事件;

在大部分情况下,我们是不需要对Windows调度程序过度关注。
深入接触Windows,会发现其不仅是多任务的,还是多线程的,程序可以有许多较为简单的执行线程构成;这些线程被视为具有较重的权值的进程,从而如程序一样被调度;程序可以有一个主线程和几个工作线程构成,如下图:

Windows 多线程机制示意图

阅读更多

《Windows游戏编程大师技巧》学习笔记(一)

一般的游戏循环结构

一个视频游戏基本上是一个连续的循环,它完成逻辑动作并以每秒30帧或更高的刷新率在屏幕上绘制图像,与动画和电影的放映原理相似,简化的游戏循环结构如下图所示:

简化的游戏循环结构示意图

对上图每一部分流程进行说明:

  1. 初始化:游戏程序执行初始化操作,如内存分配、资源检查与加载等;
  2. 进入游戏循环:代码进入到游戏主循环体内部,各种操作开始运行,直到用户退出主循环;
  3. 获取玩家输入:缓存/处理玩家通过鼠标、键盘或手柄等设备的输入信息,以备后续游戏逻辑使用;
  4. 执行游戏逻辑部分:执行诸如人工智能、物理系统等游戏逻辑的更新,更新后的数据用于渲染下一帧图像;
  5. 渲染下一帧图像:根据前述的输入和逻辑处理,游戏的下一帧动画已经具备渲染条件;渲染中的图像常被放置于不可见的缓冲区,因此玩家不会看到这一帧画面被逐步渲染的过程;渲染完成后的图像会从缓冲区中迅速拷贝至显示设备中(双缓冲原理);
  6. 同步显示:随着时间推移,渲染每一帧游戏所需要的数据量和运算量可能会有较大变化,对计算机设备的负荷也有所不同,在不加限制的情况下就会导致游戏画面刷新率(帧率)时高时低;所以必须通过定时功能来维持帧率稳定;
  7. 循环:重复执行从“进入游戏循环”开始到现在的步骤;
  8. 退出:到达这一步表示游戏将关闭并返回操作系统,执行的操作与“初始化”阶段相反:对必要的数据进行持久化,释放内存等相关资源。

游戏循环与FSM

在大多数情况下,游戏循环是一个含有大量状态的FSM(Finite State Machine,有限状态自动机),如下图所示:

游戏循环状态转换图

阅读更多

欢迎来到 Voidmatrix 的博客

重剑无锋,大巧不工

欢迎光临我的小破站,这里记录了一些本人在学习过程中产出的笔记、对于所见所闻的感悟,以及一些可能存在的、带有极强主观性和局限性的技术分享或讨论,如果你有不同的意见或者想对作者说的话,欢迎联系:Voidmatrix@qq.com

关于自己

  • 🚩廉价且功能不完善的游戏引擎内核 EtherEngine 的开发者,正在参与新一代自研引擎的制作,更多内容详见《自研引擎二三事》
  • 🏬曾任职国内游戏大厂的一线程序员,现在是与时代潮流背道而行的全职独立游戏开发者;
  • 📖拥抱开源,目前仍在不断探索游戏领域底层技术,如:图形、网络和脚本;
  • 🎞️正在创作《从零开始的C++游戏开发》系列教程,更多内容详见《视频被培训机构选做直播课了,但是我却很担忧…》
  • ❤️喜欢敲代码💻,打游戏🎮,业余健身爱好者🥊,尝试各种美食🍔,以及几乎所有肥宅喜欢的东西🥵。

关于博客

确实,缺少评论系统等功能和炫酷的开屏动画对于传统意义的个人博客来说似乎显得有点背离时代了,不过想到整个网站是由 Markdown 笔记一键导出的,没有自行车倒也合理,不过,这也是计划的一部分,庞大而臃肿的博客系统反而是我在一直试图甩掉的事情。(如果你对这件事好奇,可以来这里看看:《小说,日记,博客》

如果你有幸发现了这里,欢迎点击页面最上方的条目查看你感兴趣的栏目,如果觉得有用,也可以将本页面加入收藏夹,或者通过上文提到的联系方式与我交换博客友链,在收到消息后我一定会第一时间回复并将它按照先后顺序添加到我这简陋的博客上。

就是这样,祝大家玩的愉快~

16行代码能做什么?写一个随机图片服务器!

在经过一番旷日持久的苦战后,自己的开源游戏引擎 EtherEngine 终于迎来了 4.x 版本
更新内容
本次更新除了增加了更多系统交互 API,优化了接口调用方式和二进制数据传参缓冲区之外,更重要的是对 Network 模块 进行了十分重要的更新,让 EtherEngine 的网络模块摇身一变变成了可以与 Python 的 Requests 库 / Nodejs 的 Express 框架 功能相媲美的工具了!

EtherEngine 虽然被更名为了 EtherAPI ,但是我更习惯叫它原来的名字(因为这样更装x),它的设计思想是尽可能地简单、易上手并且易于快速开发,所以这次网络模块的更新也恰恰印证了它的这些特性:

16行代码能够做点啥?
—— 写一个随机图片服务器足够!

阅读更多