设计模式与游戏完美开发(2)
更多内容可以浏览本人博客:https://azureblog.cn/ 😊
该文章主主题内容均来自《设计模式与游戏完美开发》—蔡升达
第二篇 基础系统
第四章 游戏主要类——外观模式(Facade)
一、游戏子功能的整合
一个游戏程序常常由内部数个不同的子系统构成(如事件系统,关卡系统,成就系统等等),这些系统支持着游戏基本功能和玩法。这些子系统需要按照一定的顺序进行初始化,某些条件达成时也需要按照一定的流程替他们释放资源。并且这些子系统会彼此使用对方的功能,即不同子系统之间会进行“通信”。
通常来说,我们认为这些子系统的通信及初始化过程应当发生在“内部”,因为当有其他的程序(或者我们自己)来添加一个游戏功能系统时,最好能不用去了解其他子系统之间的相关运行过程,而仅仅通过一些相对“高级”的接口来调用其他子系统的相关功能。
上一章所提到的"战斗状态类(BattleScene)"就是一个必须使用到的游戏系统功能的客户端,根据上一章的说明,战斗状态类(BattleState)主要负责游戏战斗的运行,而《P级阵地》在进行一场战斗时,需要大部分的子系统一起合作完成.在实现时,可以先把这些子系统及相关的执行流程全都放在BattleState类之中一起完成。
在战斗系统类中实现所有子系统相关操作:
public class BattleState: ISceneState {//声明所有需要的子系统private GameEventSystem m_GameEventSystem = null;private CampSystem m_CampSystem = null;private StageSystem m_StageSystem = null;private CharacterSystem m_CharacterSystem = null;private APSystem m_ApSystem = null;private AchivementSystem m_AchievementSystem =null;public GameState(SceneStateController Controller): base(Controller) {this.StateName = "GameState";InitGameSystem();}//初始化这些子系统private void InitGameSystem() {m_GameEventySystem = new GameEventSystem();...}//子系统的更新操作private void UpdateGameSystem() {m_GameEventSystem.Update();...}
}
虽然这样的实现方式很简单,但让战斗状态类(BattleState)整个客户端去负责调用所有与游戏玩法相关的系统功能是不好的实现方式,原因是:
-
从让事情单一化(单一职责原则)这一点来看,BattleScene类负责的是游戏在"战斗状态"下的功能执行及状态切换,所以不应该负责游戏子系统的初始化,执行操作及相关的整合工作。
-
以"可重用性"来看,这种设计方式会使得BattleState类不容易转换给其他项目使用,因为BattleState类与太多特定的子系统类产生关联,必须将它们删除才能转换给其他项目,因此丧失可重用性
综合上述两个原因,将这些子系统从BattleState类中移出,整合在单一类之下,会是比较好的做法.所以,在《P级阵地》中应用了外观模式(Facade)来整合这些子系统,使它们成为单一界面并提供外界使用。
二、外观模式(Facade)的定义
“为子系统定义一组统一的接口,这个高级的接口会让子系统更容易被使用”。—GoF
其实,外观模式(Facade)是在生活中最容易碰到的模式。当我们能够利用简单的行为来操作一个复杂的系统时,当下所使用的接口,就是以外观模式(Facade)来定义的高级接口。
外观模式(Facade)的重点在于,它能将系统内部的互动细节隐藏起来,并提供一个简单方便的接口.之后客户端只需要通过这个接口,就可以操作一个复杂系统并让它们顺利运行。

参与者的说明如下:
-
client(客户端,用户):
从原本需要操作多个子系统的情况,改为只需要面对一个整合后的界面。
-
subSystem(子系统):
原本会由不同的客户端(非同一系统相关)来操作,改为只会由内部系统之间交互使用。
-
Facade(统一对外的界面):
整合所有子系统的接口及功能,并提供高级界面(或接口)供客户端使用。
接收客户端的信息后,将信息传送给负责的子系统。
三、使用外观模式实现游戏主程序
PBaseGameDefenseGame类就是"整合所有子系统,并提供高级界面的外观模式类"。

具体实现:
//PBaseDefenseGame.cs
public class PBaeDefenseGame
{//声明各个游戏子系统...private GameEventSystem m_GameEventSystem =null;...//初始化public void Initinal() {...m_GameEventSystem = new GameEventSystem(this);...}//更新操作public void Update() {...m_GameEventSystem.Update();...}//获取游戏状态、敌人数量等...
}//BattleState.cs
public class BattleState: ISceneState {public override void StateBegin() {PBaseDefenseGame.Instance.Initinal();//初始化,隐藏了其它子系统的细节}public override void StateEnd() {PBaseDefenseGame.Instance.Release();}public override void StateUpdate() {...PBaseDefenseGame.Instance.Update();...if (PBaseDefenseGame.Instance.ThisGameIsOver()) {m_Controller.SetState(new MainMenuState(m_Controller), "MainMenuState");}}
}
使用外观模式的优点:
-
使用外观模式(Facade)可将战斗状态类BattleState单一化,让该类只负责游戏在"战斗状态"下的功能执行及状态切换,不用负责串接各个游戏系统的初始化和功能调用。
-
使用外观模式(Facade)使得战斗状态类BattleScene减少了不必要的类引用及功能整合,因此增加了BattleState类被重复使用的机会。
-
节省时间
Unity3D本身提供了不少系统的Facade接口,例如物理引擎,渲染系统,动作系统,粒子系统等。
- 易于分工开发
对于一个既庞大又复杂的子系统而言,若应用外观模式(Facade),即可成为另一个Facade接口.所以,在工作 的分工配合上,开发者只需要了解对方负责系统的Facade接口类,不必深入了解其中的运行方式。
- 增加系统的安全性
隔离客户端对子系统的接触,除了能减少耦合度之外,安全性也是重点之一。
注意事项:
由于将所有子系统集中在Facade接口类中,最终会导致Facade接口类过于庞大且难以维护,当发生这种情况时,可以重构Facade接口类,将功能相近的子系统进行整合,以减少内部系统的依赖性,或是整合其他设计模式来减少Facade接口类过度膨胀。
Facade面对变化时:
随着开发需求的变更,任何游戏子系统的修改及更换,都被限制在PBaseDefenseGame这个Facade接口类内。所以,,当有新的系统需要增加时,也只会影响PBaseDefenseGame类的定义及增加对外开放的方法,这样就能使项目的变动范围减到最小。
以减少内部系统的依赖性,或是整合其他设计模式来减少Facade接口类过度膨胀。
Facade面对变化时:
随着开发需求的变更,任何游戏子系统的修改及更换,都被限制在PBaseDefenseGame这个Facade接口类内。所以,,当有新的系统需要增加时,也只会影响PBaseDefenseGame类的定义及增加对外开放的方法,这样就能使项目的变动范围减到最小。
相关文章:
设计模式与游戏完美开发(2)
更多内容可以浏览本人博客:https://azureblog.cn/ 😊 该文章主主题内容均来自《设计模式与游戏完美开发》—蔡升达 第二篇 基础系统 第四章 游戏主要类——外观模式(Facade) 一、游戏子功能的整合 一个游戏程序常常由内部数个不…...
Coroutine 基础三 —— 结构化并发(二)
1、协程的结构化异常管理 如果一个协程抛异常,它所在的整个协程树上的其他协程(向上是父协程到根协程,向下是所有后代协程)都会被取消。因此协程发生异常的后果是十分严重的。 先讲原理,再说解决方案。 协程异常的处…...
GXUOJ-算法-第一次作业
1.整数划分 问题描述 GXUOJ | 整数划分 题解 #include<bits/stdc.h> using namespace std; const int N1010,mod1e97;int n; int f[N];int main(){cin>>n;f[0]1;for(int i1;i<n;i){for(int ji;j<n;j){f[j](f[j]f[j-i])%mod;}}cout<<f[n]; } 2.汉诺塔…...
Springboot项目Druid运行时动态连接多数据源的功能
项目支持多数据库连接是个很常见的需求,这不仅是要在编译前连已经知道的多个数据库,有时还要在程序运行时连后期增加的多个数据源来获得数据。 一、编译前注册数据库连接 1.引入依赖包 <!-- springboot 3.x --><dependency><groupId&g…...
字符串匹配——KMP算法
前言 刷到字符串匹配的力扣题了【28. 实现 strStr() 】,这题简单吧用库函数做就可以,说难吧,就得引出大名鼎鼎的线性匹配算法——KMP。 目录 KMP 算法背景与原理算法优势 前缀表1. 构建Next数组2. 搜索匹配 KMP 算法背景与原理 KMP&#x…...
Qt开发技术【下拉复选框 MultiSelectComboBox 自定义全选项】
继承ComboBox完成下拉复选框 自定义全选项 效果图 整个控件继承于QCombobox类。主要修改QLineEdit、QListWidget这两部分,QComboBox提供如下接口,可以将这两部分设置为新建的QLineEdit、QListWidget对象 CMultiSelectComboBox::CMultiSelectComboBo…...
20_HTML5 SSE --[HTML5 API 学习之旅]
HTML5 Server-Sent Events (SSE) 是一种技术,它允许服务器向浏览器推送更新。与传统的轮询不同,SSE提供了真正的单向实时通信通道:服务器可以主动发送数据到客户端,而不需要客户端发起请求。这对于实现实时更新的应用非常有用&…...
jetson Orin nx + yolov8 TensorRT 加速量化 环境配置
参考【Jetson】Jetson Orin NX纯系统配置环境-CSDN博客 一 系统环境配置: 1.更换源: sudo vi /etc/apt/sources.list.d/nvidia-l4t-apt-source.list2.更新源: sudo apt upgradesudo apt updatesudo apt dist-upgrade sudo apt-get updat…...
Android Studio IDE环境配置
需要安装哪些东西: Java jdk Java Downloads | OracleAndroid Studio 下载 Android Studio 和应用工具 - Android 开发者 | Android DevelopersAndroid Sdk 现在的Android Studio版本安装时会自动安装,需要注意下安装的路径Android Studio插件…...
PTA 7-2 0/1背包问题(回溯法) 作者 王东 单位 贵州师范学院
0/1背包问题。给定一载重量为W的背包及n个重量为wi、价值为vi的物体,1≤i≤n,要求重量和恰好为W具有最大的价值。 输入格式: 第一行输入背包载重量W及背包个数n,再依次输入n行,每行为背包重量wi和价值vi。 输出格式: 第一行输出装入背包内…...
Matlab环形柱状图
数据准备: 名称 数值 Aa 21 Bb 23 Cc 35 Dd 47 保存为Excel文件后: % Load data from Excel file filename data.xlsx; % Ensure the file is in the current folder or provide full path dataTable readtable(filena…...
【AI大模型】探索GPT模型的奥秘:引领自然语言处理的新纪元
目录 🍔 GPT介绍 🍔 GPT的架构 🍔 GPT训练过程 3.1 无监督的预训练语言模型 3.2 有监督的下游任务fine-tunning 🍔 小结 学习目标 了解什么是GPT.掌握GPT的架构.掌握GPT的预训练任务. 🍔 GPT介绍 GPT是OpenAI公…...
5.Python爬虫相关
爬虫 爬虫原理 爬虫,又称网络爬虫,是一种自动获取网页内容的程序。它模拟人类浏览网页的行为,发送HTTP请求,获取网页源代码,再通过解析、提取等技术手段,获取所需数据。 HTTP请求与响应过程 爬虫首先向…...
Windows系统上配置eNSP环境的详细步骤
华为eNSP(Enterprise Network Simulation Platform)是一款针对华为数通网络设备的网络仿真平台,用于辅助工程师进行网络技术学习、方案验证和故障排查等工作。以下是在Windows系统上配置eNSP环境的详细步骤: 1. 准备工作 下载安…...
Database.NET——一款轻量级多数据库客户端工具
文章目录 Database.NET简介下载使用使用场景总结 Database.NET简介 Database.NET 是一个功能强大且易于使用的数据库管理工具,适用于多种数据库系统。它为开发者和数据库管理员提供了一个统一的界面,可以方便地管理和操作不同类型的数据库。 支持的数据…...
新浪微博C++面试题及参考答案
多态是什么?请详细解释其实现原理,例如通过虚函数表实现。 多态是面向对象编程中的一个重要概念,它允许不同的对象对同一消息或函数调用做出不同的响应,使得程序具有更好的可扩展性和灵活性。 在 C 中,多态主要通过虚函…...
计算机视觉目标检测-1
文章目录 摘要Abstract1.目标检测任务描述1.1 目标检测分类算法1.2 目标定位的简单实现思路1.2.1 回归位置 2.R-CNN2.1 目标检测-Overfeat模型2.1.1 滑动窗口 2.2 目标检测-RCNN模型2.2.1 非极大抑制(NMS) 2.3 目标检测评价指标 3.SPPNet3.1 spatial pyr…...
【物联网技术与应用】实验15:电位器传感器实验
实验15 电位器传感器实验 【实验介绍】 电位器可以帮助控制Arduino板上的LED闪烁的时间间隔。 【实验组件】 ● Arduino Uno主板* 1 ● 电位器模块* 1 ● USB电缆*1 ● 面包板* 1 ● 9V方型电池* 1 ● 跳线若干 【实验原理】 模拟电位器是模拟电子元件,模…...
java常用类(上)
笔上得来终觉浅,绝知此事要躬行 🔥 个人主页:星云爱编程 🔥 所属专栏:javase 🌷追光的人,终会万丈光芒 🎉欢迎大家点赞👍评论📝收藏⭐文章 目录 一、包装类 1.1包装类…...
包管理工具npm、yarn、pnpm、cnpm详解
1. 包管理工具 1.1 npm # 安装 $ node 自带 npm# 基本用法 npm install package # 安装包 npm install # 安装所有依赖 npm install -g package # 全局安装 npm uninstall package # 卸载包 npm update package # 更新包 npm run script #…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
